From b72cd36412dd95a37a0fee2912272e21cb42718a Mon Sep 17 00:00:00 2001 From: Peihao Yang Date: Tue, 30 May 2023 23:51:57 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=F0=9F=8E=A8=20fix=20clippy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix clippy warnings and bump to 2021 edition rust --- .github/workflows/style.yml | 4 +- Makefile | 4 +- examples/datasources/consul.rs | 6 +- examples/datasources/etcdv3.rs | 4 +- examples/datasources/k8s.rs | 2 +- examples/exporter/prometheus/prometheus.rs | 2 + middleware/actix/example/src/main.rs | 2 +- middleware/axum/example/src/main.rs | 2 +- middleware/motore/example/src/client.rs | 2 +- middleware/motore/example/src/server.rs | 2 +- middleware/rocket/example/src/fairing.rs | 2 +- middleware/rocket/example/src/guard.rs | 2 +- middleware/tonic/example/src/client.rs | 2 +- middleware/tonic/example/src/server.rs | 2 +- middleware/tower/example/src/client.rs | 2 +- middleware/tower/example/src/server.rs | 2 +- sentinel-core/Cargo.toml | 2 +- sentinel-core/src/api/{api.rs => base.rs} | 0 sentinel-core/src/api/mod.rs | 8 +-- sentinel-core/src/core/base/block_error.rs | 28 ++++---- sentinel-core/src/core/base/context.rs | 4 +- sentinel-core/src/core/base/entry.rs | 2 +- sentinel-core/src/core/base/metric_item.rs | 20 +++--- sentinel-core/src/core/base/result.rs | 31 ++++---- sentinel-core/src/core/base/slot_chain.rs | 26 ++++--- .../circuitbreaker/breaker/error_count.rs | 1 - .../circuitbreaker/breaker/error_ratio.rs | 1 - .../src/core/circuitbreaker/breaker/mod.rs | 44 ++++++------ sentinel-core/src/core/circuitbreaker/rule.rs | 4 +- .../src/core/circuitbreaker/rule_manager.rs | 52 +++++++------- sentinel-core/src/core/circuitbreaker/slot.rs | 6 +- .../src/core/config/{config.rs => base.rs} | 10 +-- sentinel-core/src/core/config/constant.rs | 4 +- sentinel-core/src/core/config/entity.rs | 4 +- sentinel-core/src/core/config/mod.rs | 4 +- sentinel-core/src/core/flow/rule.rs | 8 +-- sentinel-core/src/core/flow/rule_manager.rs | 70 +++++++++---------- .../src/core/flow/traffic_shaping/adaptive.rs | 2 +- .../core/flow/traffic_shaping/throttling.rs | 25 ++++--- sentinel-core/src/core/hotspot/cache.rs | 14 ++-- sentinel-core/src/core/hotspot/rule.rs | 10 ++- .../src/core/hotspot/rule_manager.rs | 47 ++++++------- .../src/core/hotspot/traffic_shaping/mod.rs | 42 +++++------ .../core/hotspot/traffic_shaping/reject.rs | 8 ++- .../hotspot/traffic_shaping/throttling.rs | 6 ++ sentinel-core/src/core/isolation/rule.rs | 2 +- .../src/core/isolation/rule_manager.rs | 32 ++++----- sentinel-core/src/core/isolation/slot.rs | 4 +- .../src/core/log/metric/aggregator.rs | 20 +++--- sentinel-core/src/core/log/metric/mod.rs | 27 +++---- sentinel-core/src/core/log/metric/reader.rs | 13 ++-- sentinel-core/src/core/log/metric/searcher.rs | 18 ++--- sentinel-core/src/core/log/metric/writer.rs | 25 ++++--- .../src/core/stat/base/bucket_leap_array.rs | 4 +- .../src/core/stat/base/metric_bucket.rs | 6 +- .../core/stat/base/sliding_window_metric.rs | 10 +-- sentinel-core/src/core/stat/node_storage.rs | 6 +- sentinel-core/src/core/stat/stat_slot.rs | 2 +- sentinel-core/src/core/system/rule_manager.rs | 10 +-- sentinel-core/src/core/system/slot.rs | 26 +++---- sentinel-core/src/core/system_metric.rs | 2 +- .../{datasource => adapters}/ds_consul.rs | 11 ++- .../{datasource => adapters}/ds_etcdv3.rs | 38 +++++----- .../{datasource => adapters}/ds_k8s.rs | 0 .../{datasource => adapters}/mod.rs | 6 +- sentinel-core/src/datasource/mod.rs | 4 +- sentinel-core/src/datasource/property.rs | 8 +-- sentinel-core/src/exporter.rs | 11 +-- sentinel-core/src/lib.rs | 10 +-- sentinel-core/src/utils/mod.rs | 4 +- sentinel-macros/Cargo.toml | 2 +- 71 files changed, 402 insertions(+), 424 deletions(-) rename sentinel-core/src/api/{api.rs => base.rs} (100%) rename sentinel-core/src/core/config/{config.rs => base.rs} (95%) rename sentinel-core/src/datasource/{datasource => adapters}/ds_consul.rs (93%) rename sentinel-core/src/datasource/{datasource => adapters}/ds_etcdv3.rs (84%) rename sentinel-core/src/datasource/{datasource => adapters}/ds_k8s.rs (100%) rename sentinel-core/src/datasource/{datasource => adapters}/mod.rs (96%) diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index ff903a7..c93ff63 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -35,8 +35,8 @@ jobs: run: rustup component add rustfmt - name: "rustfmt --check" run: | - if ! rustfmt --check --edition 2018 $(find . -name '*.rs' -print); then - printf "Please run \`rustfmt --edition 2018 \$(find . -name '*.rs' -print)\` to fix rustfmt errors.\nSee CONTRIBUTING.md for more details.\n" >&2 + if ! rustfmt --check --edition 2021 $(find . -name '*.rs' -print); then + printf "Please run \`rustfmt --edition 2021 \$(find . -name '*.rs' -print)\` to fix rustfmt errors.\nSee CONTRIBUTING.md for more details.\n" >&2 exit 1 fi diff --git a/Makefile b/Makefile index c9aef92..2c58a3c 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ check: cargo check --all-features clippy: - cargo clippy --all-targets + cargo clippy --all-targets --all-features doc: clean cargo doc --lib --no-deps --all-features --document-private-items @@ -14,7 +14,7 @@ clean: cargo clean fmt: - @rustfmt --edition 2018 $(SRC_FILES) + @rustfmt --edition 2021 $(SRC_FILES) unit: unit_single unit_parallel diff --git a/examples/datasources/consul.rs b/examples/datasources/consul.rs index e6abec5..b781a3c 100644 --- a/examples/datasources/consul.rs +++ b/examples/datasources/consul.rs @@ -2,9 +2,7 @@ use consul::{kv::KVPair, kv::KV, Client, Config, QueryOptions}; use sentinel_core::{ base, - datasource::{ - ds_consul::ConsulDataSource, new_flow_rule_handler, rule_json_array_parser, DataSource, - }, + datasource::{ds_consul::ConsulDataSource, new_flow_rule_handler, rule_json_array_parser}, flow, utils::sleep_for_ms, EntryBuilder, Result, @@ -34,7 +32,7 @@ fn main() -> Result<()> { }; client.put(&pair, None).unwrap(); - println!("list: {:?}", client.list(&key, None)); + println!("list: {:?}", client.list(key, None)); } // Sleep 3 seconds and then read the consul diff --git a/examples/datasources/etcdv3.rs b/examples/datasources/etcdv3.rs index 3e72be5..31c10a7 100644 --- a/examples/datasources/etcdv3.rs +++ b/examples/datasources/etcdv3.rs @@ -2,9 +2,7 @@ use etcd_rs::{Client, ClientConfig, PutRequest}; use sentinel_core::{ base, - datasource::{ - ds_etcdv3::Etcdv3DataSource, new_flow_rule_handler, rule_json_array_parser, DataSource, - }, + datasource::{ds_etcdv3::Etcdv3DataSource, new_flow_rule_handler, rule_json_array_parser}, flow, EntryBuilder, Result, }; use std::sync::Arc; diff --git a/examples/datasources/k8s.rs b/examples/datasources/k8s.rs index 8985bc6..3d7bfd9 100644 --- a/examples/datasources/k8s.rs +++ b/examples/datasources/k8s.rs @@ -131,7 +131,7 @@ async fn dynamic_update( }, ); - let flow_rule: Api = Api::namespaced(client.clone(), namespace.into()); + let flow_rule: Api = Api::namespaced(client.clone(), namespace); flow_rule.create(&PostParams::default(), &cr).await?; println!( "Dynamically change custom resource: {} to: {:?}", diff --git a/examples/exporter/prometheus/prometheus.rs b/examples/exporter/prometheus/prometheus.rs index 7e2d9d6..84dc4dc 100644 --- a/examples/exporter/prometheus/prometheus.rs +++ b/examples/exporter/prometheus/prometheus.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_update)] + use rand::prelude::*; use sentinel_core::base::Snapshot; use sentinel_core::circuitbreaker::{ diff --git a/middleware/actix/example/src/main.rs b/middleware/actix/example/src/main.rs index 12e52c1..721f8eb 100644 --- a/middleware/actix/example/src/main.rs +++ b/middleware/actix/example/src/main.rs @@ -9,7 +9,7 @@ use sentinel_actix::Sentinel; use sentinel_core::flow; use std::sync::Arc; -const RESOURCE_NAME: &'static str = "actix_example"; +const RESOURCE_NAME: &str = "actix_example"; fn custom_extractor(_req: &ServiceRequest) -> String { RESOURCE_NAME.into() diff --git a/middleware/axum/example/src/main.rs b/middleware/axum/example/src/main.rs index cbfad4f..2af762b 100644 --- a/middleware/axum/example/src/main.rs +++ b/middleware/axum/example/src/main.rs @@ -13,7 +13,7 @@ use std::net::SocketAddr; use std::sync::Arc; use tower::ServiceBuilder; -const RESOURCE_NAME: &'static str = "axum_example"; +const RESOURCE_NAME: &str = "axum_example"; type Request = http::Request; diff --git a/middleware/motore/example/src/client.rs b/middleware/motore/example/src/client.rs index e795ef0..8982063 100644 --- a/middleware/motore/example/src/client.rs +++ b/middleware/motore/example/src/client.rs @@ -11,7 +11,7 @@ use volo_grpc::{ Request, Response, }; -const RESOURCE_NAME: &'static str = "motore_example"; +const RESOURCE_NAME: &str = "motore_example"; fn custom_extractor(_cx: &ClientContext, _req: &Request) -> String { RESOURCE_NAME.into() diff --git a/middleware/motore/example/src/server.rs b/middleware/motore/example/src/server.rs index 2e882e2..b5c3721 100644 --- a/middleware/motore/example/src/server.rs +++ b/middleware/motore/example/src/server.rs @@ -12,7 +12,7 @@ use volo_grpc::{ Request, Response, }; -const RESOURCE_NAME: &'static str = "motore_example"; +const RESOURCE_NAME: &str = "motore_example"; fn custom_extractor(_cx: &ServerContext, _req: &Request) -> String { RESOURCE_NAME.into() diff --git a/middleware/rocket/example/src/fairing.rs b/middleware/rocket/example/src/fairing.rs index ef8dbfe..5b5a45c 100644 --- a/middleware/rocket/example/src/fairing.rs +++ b/middleware/rocket/example/src/fairing.rs @@ -3,7 +3,7 @@ use sentinel_core::flow; use sentinel_rocket::{SentinelFairing, SentinelFairingState}; use std::sync::Arc; -const RESOURCE_NAME: &'static str = "rocket_example"; +const RESOURCE_NAME: &str = "rocket_example"; fn custom_extractor(_req: &Request<'_>) -> String { RESOURCE_NAME.into() diff --git a/middleware/rocket/example/src/guard.rs b/middleware/rocket/example/src/guard.rs index 1b6de0d..a4ea3d9 100644 --- a/middleware/rocket/example/src/guard.rs +++ b/middleware/rocket/example/src/guard.rs @@ -3,7 +3,7 @@ use sentinel_core::flow; use sentinel_rocket::{SentinelConfigForGuard, SentinelGuard}; use std::sync::Arc; -const RESOURCE_NAME: &'static str = "rocket_example"; +const RESOURCE_NAME: &str = "rocket_example"; fn custom_extractor(_req: &Request<'_>) -> String { RESOURCE_NAME.into() diff --git a/middleware/tonic/example/src/client.rs b/middleware/tonic/example/src/client.rs index cc79575..681ecd4 100644 --- a/middleware/tonic/example/src/client.rs +++ b/middleware/tonic/example/src/client.rs @@ -9,7 +9,7 @@ pub mod hello_world { tonic::include_proto!("helloworld"); } -const RESOURCE_NAME: &'static str = "tonic_example"; +const RESOURCE_NAME: &str = "tonic_example"; fn custom_extractor(_req: &Request<()>) -> String { RESOURCE_NAME.into() diff --git a/middleware/tonic/example/src/server.rs b/middleware/tonic/example/src/server.rs index ec1fb35..6b104a6 100644 --- a/middleware/tonic/example/src/server.rs +++ b/middleware/tonic/example/src/server.rs @@ -9,7 +9,7 @@ pub mod hello_world { tonic::include_proto!("helloworld"); } -const RESOURCE_NAME: &'static str = "tonic_example"; +const RESOURCE_NAME: &str = "tonic_example"; fn custom_extractor(_req: &Request<()>) -> String { RESOURCE_NAME.into() diff --git a/middleware/tower/example/src/client.rs b/middleware/tower/example/src/client.rs index c5bc831..0d9bf16 100644 --- a/middleware/tower/example/src/client.rs +++ b/middleware/tower/example/src/client.rs @@ -10,7 +10,7 @@ pub mod hello_world { tonic::include_proto!("helloworld"); } -const RESOURCE_NAME: &'static str = "tonic_example"; +const RESOURCE_NAME: &str = "tonic_example"; type Request = http::Request; // type Response = http::Response; diff --git a/middleware/tower/example/src/server.rs b/middleware/tower/example/src/server.rs index 2803e43..cbd867c 100644 --- a/middleware/tower/example/src/server.rs +++ b/middleware/tower/example/src/server.rs @@ -17,7 +17,7 @@ pub mod hello_world { tonic::include_proto!("helloworld"); } -const RESOURCE_NAME: &'static str = "tonic_example"; +const RESOURCE_NAME: &str = "tonic_example"; type Request = http::Request; type Response = http::Response; diff --git a/sentinel-core/Cargo.toml b/sentinel-core/Cargo.toml index d073564..944718c 100644 --- a/sentinel-core/Cargo.toml +++ b/sentinel-core/Cargo.toml @@ -2,7 +2,7 @@ name = "sentinel-core" version = "0.1.3" authors = ["Forsworns <378974295@qq.com>"] -edition = "2018" +edition = "2021" license = "Apache-2.0" readme = "README.md" documentation = "https://docs.rs/sentinel-core/latest" diff --git a/sentinel-core/src/api/api.rs b/sentinel-core/src/api/base.rs similarity index 100% rename from sentinel-core/src/api/api.rs rename to sentinel-core/src/api/base.rs diff --git a/sentinel-core/src/api/mod.rs b/sentinel-core/src/api/mod.rs index 5f448e7..d276bc1 100644 --- a/sentinel-core/src/api/mod.rs +++ b/sentinel-core/src/api/mod.rs @@ -6,10 +6,10 @@ //! 3. `init_with_config_file(config_path: String)`, using yaml file to initialize. //! For the examples, visit the [Sentinel repository](https://github.com/sentinel-group/sentinel-rust) -pub mod api; -pub mod init; -pub mod slot_chain; +mod base; +mod init; +mod slot_chain; -pub use api::*; +pub use base::*; pub use init::*; pub use slot_chain::*; diff --git a/sentinel-core/src/core/base/block_error.rs b/sentinel-core/src/core/base/block_error.rs index b0f7076..f61fbc6 100644 --- a/sentinel-core/src/core/base/block_error.rs +++ b/sentinel-core/src/core/base/block_error.rs @@ -75,7 +75,7 @@ impl BlockError { impl fmt::Display for BlockError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.block_msg.len() == 0 { + if self.block_msg.is_empty() { write!(f, "SentinelBlockError: {}", self.block_type) } else { write!( @@ -97,7 +97,7 @@ mod test { impl SentinelRule for MockRule { fn resource_name(&self) -> String { - return "mock resource".into(); + "mock resource".into() } } @@ -130,20 +130,18 @@ mod test { &block_err.triggered_value().unwrap(), &snapshot_value )); + } else if let Some(block_msg) = block_msg { + block_err = BlockError::new_with_msg(block_type, block_msg.clone()); + assert_eq!(block_err.block_type, block_type); + assert_eq!(block_err.block_msg, block_msg); + assert!(block_err.triggered_rule().is_none()); + assert!(block_err.triggered_value().is_none()); } else { - if let Some(block_msg) = block_msg { - block_err = BlockError::new_with_msg(block_type, block_msg.clone()); - assert_eq!(block_err.block_type, block_type); - assert_eq!(block_err.block_msg, block_msg); - assert_eq!(block_err.triggered_rule().is_none(), true); - assert_eq!(block_err.triggered_value().is_none(), true); - } else { - block_err = BlockError::new(block_type); - assert_eq!(block_err.block_type, block_type); - assert_eq!(block_err.block_msg, String::default()); - assert_eq!(block_err.triggered_rule().is_none(), true); - assert_eq!(block_err.triggered_value().is_none(), true); - } + block_err = BlockError::new(block_type); + assert_eq!(block_err.block_type, block_type); + assert_eq!(block_err.block_msg, String::default()); + assert!(block_err.triggered_rule().is_none()); + assert!(block_err.triggered_value().is_none()); } } diff --git a/sentinel-core/src/core/base/context.rs b/sentinel-core/src/core/base/context.rs index 4e38afe..6ce82fb 100644 --- a/sentinel-core/src/core/base/context.rs +++ b/sentinel-core/src/core/base/context.rs @@ -179,8 +179,8 @@ mod test { #[test] fn is_blocked() { let mut ctx = EntryContext::new(); - assert_eq!(ctx.is_blocked(), false); + assert!(!ctx.is_blocked()); ctx.set_result(TokenResult::new_blocked(BlockType::Other(1))); - assert_eq!(ctx.is_blocked(), true); + assert!(ctx.is_blocked()); } } diff --git a/sentinel-core/src/core/base/entry.rs b/sentinel-core/src/core/base/entry.rs index 9c87a3e..c765b85 100644 --- a/sentinel-core/src/core/base/entry.rs +++ b/sentinel-core/src/core/base/entry.rs @@ -46,7 +46,7 @@ impl SentinelEntry { // todo: cleanup pub fn exit(&self) { for handler in &self.exit_handlers { - handler(&self, self.ctx.clone()) // Rc/Arc clone + handler(self, self.ctx.clone()) // Rc/Arc clone .map_err(|err: Error| { logging::error!("ERROR: {}", err); }) diff --git a/sentinel-core/src/core/base/metric_item.rs b/sentinel-core/src/core/base/metric_item.rs index fb99da5..cbf405f 100644 --- a/sentinel-core/src/core/base/metric_item.rs +++ b/sentinel-core/src/core/base/metric_item.rs @@ -50,21 +50,23 @@ impl fmt::Display for MetricItem { impl MetricItem { /// cannot use String trait, since conversion may fail pub fn from_string(line: &str) -> Result { - if line.len() == 0 { + if line.is_empty() { return Err(Error::msg(METRIC_EMPTY_STRING_ERROR)); } let arr: Vec<&str> = line.split(METRIC_PART_SEPARATOR).collect(); if arr.len() < 8 { return Err(Error::msg(METRIC_INVALID_FORMAT_ERROR)); } - let mut item = MetricItem::default(); - item.timestamp = arr[0].parse::()?; - item.resource = arr[2].into(); - item.pass_qps = arr[3].parse::()?; - item.block_qps = arr[4].parse::()?; - item.complete_qps = arr[5].parse::()?; - item.error_qps = arr[6].parse::()?; - item.avg_rt = arr[7].parse::()?; + let mut item = MetricItem { + timestamp: arr[0].parse::()?, + resource: arr[2].into(), + pass_qps: arr[3].parse::()?, + block_qps: arr[4].parse::()?, + complete_qps: arr[5].parse::()?, + error_qps: arr[6].parse::()?, + avg_rt: arr[7].parse::()?, + ..Default::default() + }; if arr.len() >= 9 { item.occupied_pass_qps = arr[8].parse::()?; if arr.len() >= 10 { diff --git a/sentinel-core/src/core/base/result.rs b/sentinel-core/src/core/base/result.rs index df9e760..bbfd9e3 100644 --- a/sentinel-core/src/core/base/result.rs +++ b/sentinel-core/src/core/base/result.rs @@ -36,11 +36,13 @@ const EXIST_BLOCK_ERROR: &str = "Block type existed!"; pub fn registry_block_type(other: BlockType, desc: &'static str) -> Result<()> { match other { BlockType::Other(id) => { - if BLOCK_TYPE_MAP.lock().unwrap().contains_key(&id) { - Err(Error::msg(EXIST_BLOCK_ERROR)) - } else { - BLOCK_TYPE_MAP.lock().unwrap().insert(id, desc); + if let std::collections::hash_map::Entry::Vacant(e) = + BLOCK_TYPE_MAP.lock().unwrap().entry(id) + { + e.insert(desc); Ok(()) + } else { + Err(Error::msg(EXIST_BLOCK_ERROR)) } } _ => Err(Error::msg(EXIST_BLOCK_ERROR)), @@ -51,11 +53,11 @@ impl fmt::Display for BlockType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let BlockType::Other(id) = self { match BLOCK_TYPE_MAP.lock().unwrap().get(id) { - Some(&desc) => return write!(f, "{}", desc), - None => return write!(f, "{}", id), + Some(&desc) => write!(f, "{}", desc), + None => write!(f, "{}", id), } } else { - return write!(f, "{:?}", self); + write!(f, "{:?}", self) } } } @@ -127,24 +129,15 @@ impl TokenResult { } pub fn is_pass(&self) -> bool { - match self { - Self::Pass => true, - _ => false, - } + matches!(self, Self::Pass) } pub fn is_blocked(&self) -> bool { - match self { - Self::Blocked(_) => true, - _ => false, - } + matches!(self, Self::Blocked(_)) } pub fn is_wait(&self) -> bool { - match self { - Self::Wait(_) => true, - _ => false, - } + matches!(self, Self::Wait(_)) } pub fn block_err(&self) -> Option { diff --git a/sentinel-core/src/core/base/slot_chain.rs b/sentinel-core/src/core/base/slot_chain.rs index 9eafb53..541c7dd 100644 --- a/sentinel-core/src/core/base/slot_chain.rs +++ b/sentinel-core/src/core/base/slot_chain.rs @@ -67,14 +67,20 @@ pub struct SlotChain { pub(self) stats: Vec>, } -impl SlotChain { - pub fn new() -> Self { +impl Default for SlotChain { + fn default() -> Self { Self { stat_pres: Vec::with_capacity(SLOT_INIT), rule_checks: Vec::with_capacity(SLOT_INIT), stats: Vec::with_capacity(SLOT_INIT), } } +} + +impl SlotChain { + pub fn new() -> Self { + Default::default() + } pub fn exit(&self, ctx_ptr: ContextPtr) { let mut ctx = ctx_ptr.write().unwrap(); @@ -87,7 +93,7 @@ impl SlotChain { } // The on_completed is called only when entry passed for s in &self.stats { - s.on_completed(&mut *ctx); + s.on_completed(&mut ctx); } } @@ -124,13 +130,13 @@ impl SlotChain { let mut ctx = ctx_ptr.write().unwrap(); // execute prepare slot for s in &self.stat_pres { - s.prepare(&mut *ctx); // Rc/Arc clone + s.prepare(&mut ctx); // Rc/Arc clone } // execute rule based checking slot ctx.reset_result_to_pass(); for s in &self.rule_checks { - let res = s.check(&mut *ctx); + let res = s.check(&mut ctx); // check slot result if res.is_blocked() { ctx.set_result(res.clone()); @@ -141,10 +147,10 @@ impl SlotChain { for s in &self.stats { // indicate the result of rule based checking slot. if ctx.result().is_pass() { - s.on_entry_pass(&*ctx) // Rc/Arc clone + s.on_entry_pass(&ctx) // Rc/Arc clone } else if ctx.result().is_blocked() { // The block error should not be none. - s.on_entry_blocked(&*ctx, ctx.result().block_err().unwrap()) // Rc/Arc clone + s.on_entry_blocked(&ctx, ctx.result().block_err().unwrap()) // Rc/Arc clone } } ctx.result().clone() @@ -183,7 +189,7 @@ mod test { for i in 0..10 { let order = base * 10 + i; sc.add_stat_prepare_slot(Arc::new(StatPrepareSlotMock { - name: String::from(format!("mock{}", order)), + name: format!("mock{}", order), order, })) } @@ -218,7 +224,7 @@ mod test { for i in 0..10 { let order = base * 10 + i; sc.add_rule_check_slot(Arc::new(RuleCheckSlotMock { - name: String::from(format!("mock{}", order)), + name: format!("mock{}", order), order, })) } @@ -253,7 +259,7 @@ mod test { for i in 0..10 { let order = base * 10 + i; sc.add_stat_slot(Arc::new(StatSlotMock { - name: String::from(format!("mock{}", order)), + name: format!("mock{}", order), order, })) } diff --git a/sentinel-core/src/core/circuitbreaker/breaker/error_count.rs b/sentinel-core/src/core/circuitbreaker/breaker/error_count.rs index 4b95a50..0d0caae 100644 --- a/sentinel-core/src/core/circuitbreaker/breaker/error_count.rs +++ b/sentinel-core/src/core/circuitbreaker/breaker/error_count.rs @@ -79,7 +79,6 @@ impl CircuitBreakerTrait for ErrorCountBreaker { } else { self.breaker.from_half_open_to_open(Arc::new(1)); } - return; } State::Closed => { if total_count >= self.min_request_amount diff --git a/sentinel-core/src/core/circuitbreaker/breaker/error_ratio.rs b/sentinel-core/src/core/circuitbreaker/breaker/error_ratio.rs index d61b6cc..ff43b4b 100644 --- a/sentinel-core/src/core/circuitbreaker/breaker/error_ratio.rs +++ b/sentinel-core/src/core/circuitbreaker/breaker/error_ratio.rs @@ -79,7 +79,6 @@ impl CircuitBreakerTrait for ErrorRatioBreaker { } else { self.breaker.from_half_open_to_open(Arc::new(1)); } - return; } State::Closed => { if total_count >= self.min_request_amount diff --git a/sentinel-core/src/core/circuitbreaker/breaker/mod.rs b/sentinel-core/src/core/circuitbreaker/breaker/mod.rs index f914bfe..e2b4365 100644 --- a/sentinel-core/src/core/circuitbreaker/breaker/mod.rs +++ b/sentinel-core/src/core/circuitbreaker/breaker/mod.rs @@ -2,18 +2,20 @@ //! //! switch to open based on rule //! -//! +-----------------------------------------------------------------------+ -//! | | -//! | v -//! +----------------+ +----------------+ Probe +----------------+ -//! | | | |<----------------| | -//! | | Probe succeed | | | | -//! | Closed |<------------------| HalfOpen | | Open | -//! | | | | Probe failed | | -//! | | | +---------------->| | -//! +----------------+ +----------------+ +----------------+ +//! +-----------------------------------------------------------------------+ +//! | | +//! | v +//! +----------------+ +----------------+ Probe +----------------+ +//! | | | |<----------------| | +//! | | Probe succeed | | | | +//! | Closed |<------------------| HalfOpen | | Open | +//! | | | | Probe failed | | +//! | | | +---------------->| | +//! +----------------+ +----------------+ +----------------+ //! +#![allow(clippy::wrong_self_convention)] + /// Error count pub mod error_count; /// Error ratio @@ -256,17 +258,11 @@ impl BreakerBase { listener.on_transform_to_half_open(State::Open, Arc::clone(&self.rule)); } let entry = ctx.entry(); - if entry.is_none() { - logging::error!( - "Entry is None in BreakerBase::from_open_to_half_open(), rule: {:?}", - self.rule, - ); - } else { + if let Some(entry) = entry { // add hook for entry exit // if the current circuit breaker performs the probe through this entry, but the entry was blocked, // this hook will guarantee current circuit breaker state machine will rollback to Open from Half-Open drop(state); - let entry = entry.unwrap(); let entry = entry.upgrade().unwrap(); let rule = Arc::clone(&self.rule); let state = Arc::clone(&self.state); @@ -289,8 +285,12 @@ impl BreakerBase { Ok(()) }, )) + } else { + logging::error!( + "Entry is None in BreakerBase::from_open_to_half_open(), rule: {:?}", + self.rule, + ); } - #[cfg(feature = "exporter")] crate::exporter::add_state_change_counter(&self.rule.resource, "Open", "HalfOpen"); true @@ -452,7 +452,7 @@ pub(crate) mod test { Arc::clone(&sc), ))); ctx.write().unwrap().set_entry(Arc::downgrade(&entry)); - let token = breaker.try_pass(&*ctx.read().unwrap()); + let token = breaker.try_pass(&ctx.read().unwrap()); clear_state_change_listeners(); assert!(token); assert_eq!(breaker.current_state(), State::HalfOpen); @@ -501,7 +501,7 @@ pub(crate) mod test { Arc::clone(&sc), ))); ctx.write().unwrap().set_entry(Arc::downgrade(&entry)); - let token = breaker.try_pass(&*ctx.read().unwrap()); + let token = breaker.try_pass(&ctx.read().unwrap()); assert!(token); assert_eq!(breaker.current_state(), State::HalfOpen); } @@ -577,7 +577,7 @@ pub(crate) mod test { Arc::clone(&sc), ))); ctx.write().unwrap().set_entry(Arc::downgrade(&entry)); - let token = breaker.try_pass(&*ctx.read().unwrap()); + let token = breaker.try_pass(&ctx.read().unwrap()); assert!(token); assert_eq!(breaker.current_state(), State::HalfOpen); } @@ -652,7 +652,7 @@ pub(crate) mod test { Arc::clone(&sc), ))); ctx.write().unwrap().set_entry(Arc::downgrade(&entry)); - let token = breaker.try_pass(&*ctx.read().unwrap()); + let token = breaker.try_pass(&ctx.read().unwrap()); assert!(token); assert_eq!(breaker.current_state(), State::HalfOpen); } diff --git a/sentinel-core/src/core/circuitbreaker/rule.rs b/sentinel-core/src/core/circuitbreaker/rule.rs index c1beec8..f8f0c66 100644 --- a/sentinel-core/src/core/circuitbreaker/rule.rs +++ b/sentinel-core/src/core/circuitbreaker/rule.rs @@ -87,7 +87,7 @@ impl Rule { if bucket_count == 0 || self.stat_interval_ms % bucket_count != 0 { bucket_count = 1 } - return bucket_count; + bucket_count } } @@ -97,7 +97,7 @@ impl SentinelRule for Rule { } fn is_valid(&self) -> crate::Result<()> { - if self.resource.len() == 0 { + if self.resource.is_empty() { return Err(Error::msg("empty resource name")); } if self.stat_interval_ms == 0 { diff --git a/sentinel-core/src/core/circuitbreaker/rule_manager.rs b/sentinel-core/src/core/circuitbreaker/rule_manager.rs index 559df87..5f87fdc 100644 --- a/sentinel-core/src/core/circuitbreaker/rule_manager.rs +++ b/sentinel-core/src/core/circuitbreaker/rule_manager.rs @@ -96,7 +96,7 @@ pub fn get_rules_of_resource(res: &String) -> Vec> { pub fn get_rules() -> Vec> { let mut rules = Vec::new(); let breaker_rules = BREAKER_RULES.read().unwrap(); - for (_, res_rules) in &*breaker_rules { + for res_rules in (*breaker_rules).values() { for r in res_rules { rules.push(Arc::clone(r)); } @@ -129,13 +129,13 @@ pub fn append_rule(rule: Arc) -> bool { .lock() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(Arc::clone(&rule)); BREAKER_RULES .write() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(Arc::clone(&rule)); } Err(err) => logging::warn!( @@ -147,19 +147,19 @@ pub fn append_rule(rule: Arc) -> bool { let mut placeholder = Vec::new(); let new_tcs_of_res = build_resource_circuit_breaker( &rule.resource, - &BREAKER_RULES.read().unwrap().get(&rule.resource).unwrap(), + BREAKER_RULES.read().unwrap().get(&rule.resource).unwrap(), BREAKER_MAP .write() .unwrap() .get_mut(&rule.resource) .unwrap_or(&mut placeholder), ); - if new_tcs_of_res.len() > 0 { + if !new_tcs_of_res.is_empty() { BREAKER_MAP .write() .unwrap() .entry(rule.resource.clone()) - .or_insert(Vec::new()) + .or_default() .push(Arc::clone(&new_tcs_of_res[0])); } true @@ -176,14 +176,12 @@ pub fn load_rules(rules: Vec>) -> bool { // instead of dealing with them in // `on_rule_update` for rule in rules { - let entry = rule_map - .entry(rule.resource.clone()) - .or_insert(HashSet::new()); + let entry = rule_map.entry(rule.resource.clone()).or_default(); entry.insert(rule); } let mut global_rule_map = CURRENT_RULES.lock().unwrap(); - if &*global_rule_map == &rule_map { + if *global_rule_map == rule_map { logging::info!( "[CircuitBreakerTrait] Loaded rules is the same with current rules, so ignore load operation." ); @@ -198,7 +196,7 @@ pub fn load_rules(rules: Vec>) -> bool { for rule in rules { match rule.is_valid() { Ok(_) => { - valid_rules.insert(Arc::clone(&rule)); + valid_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[Flow load_rules] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -207,7 +205,7 @@ pub fn load_rules(rules: Vec>) -> bool { ), } } - if valid_rules.len() > 0 { + if !valid_rules.is_empty() { valid_rules_map.insert(res.clone(), valid_rules); } } @@ -221,15 +219,15 @@ pub fn load_rules(rules: Vec>) -> bool { let mut placeholder = Vec::new(); let new_cbs_of_res = build_resource_circuit_breaker( res, - &rules, + rules, global_breaker_map.get_mut(res).unwrap_or(&mut placeholder), ); - if new_cbs_of_res.len() > 0 { + if !new_cbs_of_res.is_empty() { valid_breaker_map.insert(res.clone(), new_cbs_of_res); } } - if valid_rules_map.len() == 0 { + if valid_rules_map.is_empty() { logging::info!("[Circuit Breaker] Circuit breaking rules were cleared") } else { logging::info!( @@ -248,7 +246,7 @@ pub fn load_rules(rules: Vec>) -> bool { utils::curr_time_nanos() - start ); - return true; + true } /// load_rulesOfResource loads the given resource's circuitBreaker rules to the rule manager, while all previous resource's rules will be replaced. @@ -256,14 +254,14 @@ pub fn load_rules(rules: Vec>) -> bool { // This func acquires locks on global `CURRENT_RULES`, `BREAKER_RULES` and `BREAKER_MAP`, // please release your locks on them before calling this func pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - if res.len() == 0 { + if res.is_empty() { return Err(Error::msg("empty resource")); } let rules: HashSet<_> = rules.into_iter().collect(); let mut global_rule_map = CURRENT_RULES.lock().unwrap(); let mut global_breaker_map = BREAKER_MAP.write().unwrap(); // clear resource rules - if rules.len() == 0 { + if rules.is_empty() { global_rule_map.remove(res); global_breaker_map.remove(res); BREAKER_RULES.write().unwrap().remove(res); @@ -282,7 +280,7 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result {valid_res_rules.insert(Arc::clone(&rule));}, + Ok(_) => {valid_res_rules.insert(Arc::clone(rule));}, Err(err) => logging::warn!( "CircuitBreakerTrait onResourceRuleUpdate] Ignoring invalid circuitBreaker rule {:?}, reason: {:?}", rule, @@ -293,12 +291,12 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result Vec>) { - if listeners.len() == 0 { + if listeners.is_empty() { return; } STATE_CHANGE_LISTERNERS @@ -372,7 +370,7 @@ pub fn set_circuit_breaker_generator( pub fn remove_circuit_breaker_generator(s: &BreakerStrategy) -> Result<()> { match s { BreakerStrategy::Custom(_) => { - GEN_FUN_MAP.write().unwrap().remove(&s); + GEN_FUN_MAP.write().unwrap().remove(s); Ok(()) } _ => Err(Error::msg( @@ -390,7 +388,7 @@ pub fn clear_rules_of_resource(res: &String) { pub fn calculate_reuse_index_for( r: &Arc, - old_res_cbs: &Vec>, + old_res_cbs: &[Arc], ) -> (usize, usize) { // the index of equivalent rule in old circuit breaker slice let mut eq_idx = usize::MAX; @@ -462,7 +460,7 @@ pub fn build_resource_circuit_breaker( } new_res_cbs.push(cb); } - return new_res_cbs; + new_res_cbs } #[cfg(test)] @@ -521,7 +519,7 @@ mod test { let breaker_map = BREAKER_MAP.write().unwrap(); assert!(GEN_FUN_MAP.read().unwrap().contains_key(&key)); - assert!(breaker_map[&resource].len() > 0); + assert!(!breaker_map[&resource].is_empty()); remove_circuit_breaker_generator(&key).unwrap(); assert!(!GEN_FUN_MAP.read().unwrap().contains_key(&key)); drop(breaker_map); diff --git a/sentinel-core/src/core/circuitbreaker/slot.rs b/sentinel-core/src/core/circuitbreaker/slot.rs index e9b99e9..56089ad 100644 --- a/sentinel-core/src/core/circuitbreaker/slot.rs +++ b/sentinel-core/src/core/circuitbreaker/slot.rs @@ -25,10 +25,10 @@ impl BaseSlot for Slot { impl RuleCheckSlot for Slot { fn check(&self, ctx: &mut EntryContext) -> TokenResult { let res = ctx.resource().name().clone(); - if res.len() == 0 { + if res.is_empty() { return ctx.result().clone(); } - if let Some(_) = can_pass_check(ctx, &res) { + if can_pass_check(ctx, &res).is_some() { ctx.set_result(TokenResult::new_blocked_with_msg( BlockType::CircuitBreaking, "circuit breaker check blocked".into(), @@ -47,7 +47,7 @@ fn can_pass_check(ctx: &EntryContext, res: &String) -> Option> { return Some(Arc::clone(breaker.bound_rule())); } } - return None; + None } #[cfg(test)] diff --git a/sentinel-core/src/core/config/config.rs b/sentinel-core/src/core/config/base.rs similarity index 95% rename from sentinel-core/src/core/config/config.rs rename to sentinel-core/src/core/config/base.rs index 3cf023e..b587b55 100644 --- a/sentinel-core/src/core/config/config.rs +++ b/sentinel-core/src/core/config/base.rs @@ -30,13 +30,13 @@ pub fn init_config_with_yaml(config_path: &mut String) -> Result<()> { // apply_yaml_config_file loads general configuration from the given YAML file. fn apply_yaml_config_file(config_path: &mut String) -> Result<()> { // Priority: system environment > YAML file > default config - if utils::is_blank(&config_path) { + if utils::is_blank(config_path) { // If the config file path is absent, Sentinel will try to resolve it from the system env. - *config_path = env::var(CONF_FILE_PATH_ENV_KEY).unwrap_or(CONFIG_FILENAME.into()); + *config_path = env::var(CONF_FILE_PATH_ENV_KEY).unwrap_or_else(|_| CONFIG_FILENAME.into()); } // First Sentinel will try to load config from the given file. // If the path is empty (not set), Sentinel will use the default config. - load_global_config_from_yaml_file(&config_path)?; + load_global_config_from_yaml_file(config_path)?; Ok(()) } @@ -65,7 +65,7 @@ fn load_global_config_from_yaml_file(path_str: &String) -> Result<()> { } fn override_items_from_system_env() -> Result<()> { - let app_name = env::var(APP_NAME_ENV_KEY).unwrap_or(DEFAULT_APP_NAME.into()); + let app_name = env::var(APP_NAME_ENV_KEY).unwrap_or_else(|_| DEFAULT_APP_NAME.into()); let app_type: ResourceType = env::var(APP_TYPE_ENV_KEY) .unwrap_or(format!("{}", DEFAULT_APP_TYPE)) .parse::() @@ -136,7 +136,7 @@ pub fn app_name() -> String { #[inline] pub fn app_type() -> ResourceType { GLOBAL_CONFIG - .try_with(|c| c.borrow().config.app.app_type.clone()) + .try_with(|c| c.borrow().config.app.app_type) .unwrap() } diff --git a/sentinel-core/src/core/config/constant.rs b/sentinel-core/src/core/config/constant.rs index 95c7ec9..a3a2885 100644 --- a/sentinel-core/src/core/config/constant.rs +++ b/sentinel-core/src/core/config/constant.rs @@ -13,8 +13,8 @@ pub const CONFIG_FILENAME: &str = "USE_DEFAULT_CONFIGURATION"; pub const FLUSH_INTERVAL_SEC: u32 = 1; pub const SINGLE_FILE_MAX_SIZE: u64 = 100; // 1024 * 1024 * 50; pub const MAX_FILE_AMOUNT: usize = 2; //8; -pub const EXPORTER_ADDR: &'static str = "127.0.0.1:9091"; -pub const EXPORTER_METRICS_PATH: &'static str = "/metrics"; +pub const EXPORTER_ADDR: &str = "127.0.0.1:9091"; +pub const EXPORTER_METRICS_PATH: &str = "/metrics"; // default statistic settings pub const SYSTEM_INTERVAL_MS: u32 = 1000; diff --git a/sentinel-core/src/core/config/entity.rs b/sentinel-core/src/core/config/entity.rs index 7afe17a..19c8496 100644 --- a/sentinel-core/src/core/config/entity.rs +++ b/sentinel-core/src/core/config/entity.rs @@ -172,10 +172,10 @@ impl ConfigEntity { } pub fn check(&self) -> Result<()> { - if self.version.len() == 0 { + if self.version.is_empty() { return Err(Error::msg("empty version")); } - if self.config.app.app_name.len() == 0 { + if self.config.app.app_name.is_empty() { return Err(Error::msg("empty app name")); } if self.config.log.metric.max_file_count == 0 { diff --git a/sentinel-core/src/core/config/mod.rs b/sentinel-core/src/core/config/mod.rs index 60b6af4..e3691d2 100644 --- a/sentinel-core/src/core/config/mod.rs +++ b/sentinel-core/src/core/config/mod.rs @@ -1,7 +1,7 @@ -mod config; +mod base; mod constant; mod entity; -pub use config::*; +pub use base::*; pub use constant::*; pub use entity::*; diff --git a/sentinel-core/src/core/flow/rule.rs b/sentinel-core/src/core/flow/rule.rs index 425bac2..607af5b 100644 --- a/sentinel-core/src/core/flow/rule.rs +++ b/sentinel-core/src/core/flow/rule.rs @@ -151,8 +151,8 @@ impl Rule { } pub fn need_statistic(&self) -> bool { - return self.calculate_strategy == CalculateStrategy::WarmUp - || self.control_strategy == ControlStrategy::Reject; + self.calculate_strategy == CalculateStrategy::WarmUp + || self.control_strategy == ControlStrategy::Reject } } @@ -162,13 +162,13 @@ impl SentinelRule for Rule { } fn is_valid(&self) -> crate::Result<()> { - if self.resource.len() == 0 { + if self.resource.is_empty() { return Err(Error::msg("empty resource name")); } if self.threshold < 0.0 { return Err(Error::msg("negative threshold")); } - if self.relation_strategy == RelationStrategy::Associated && self.ref_resource.len() == 0 { + if self.relation_strategy == RelationStrategy::Associated && self.ref_resource.is_empty() { return Err(Error::msg("ref_resource must be non empty when relation_strategy is RelationStrategy::Associated")); } if self.calculate_strategy == CalculateStrategy::WarmUp { diff --git a/sentinel-core/src/core/flow/rule_manager.rs b/sentinel-core/src/core/flow/rule_manager.rs index 04f20ea..f7bfe1e 100644 --- a/sentinel-core/src/core/flow/rule_manager.rs +++ b/sentinel-core/src/core/flow/rule_manager.rs @@ -95,7 +95,7 @@ lazy_static! { } fn log_rule_update(map: &RuleMap) { - if map.len() == 0 { + if map.is_empty() { logging::info!("[FlowRuleManager] Flow rules were cleared") } else { logging::info!( @@ -122,7 +122,7 @@ pub fn append_rule(rule: Arc) -> bool { .lock() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(Arc::clone(&rule)); } Err(err) => logging::warn!( @@ -141,12 +141,12 @@ pub fn append_rule(rule: Arc) -> bool { .get_mut(&rule.resource) .unwrap_or(&mut placeholder), ); - if new_tcs_of_res.len() > 0 { + if !new_tcs_of_res.is_empty() { CONTROLLER_MAP .lock() .unwrap() .entry(rule.resource.clone()) - .or_insert(Vec::new()) + .or_default() .push(Arc::clone(&new_tcs_of_res[0])); } true @@ -163,14 +163,12 @@ pub fn load_rules(rules: Vec>) -> bool { // instead of dealing with them in // `on_rule_update` for rule in rules { - let entry = rule_map - .entry(rule.resource.clone()) - .or_insert(HashSet::new()); + let entry = rule_map.entry(rule.resource.clone()).or_default(); entry.insert(rule); } let mut global_rule_map = RULE_MAP.lock().unwrap(); - if &*global_rule_map == &rule_map { + if *global_rule_map == rule_map { logging::info!( "[Flow] Load rules is the same with current rules, so ignore load operation." ); @@ -184,7 +182,7 @@ pub fn load_rules(rules: Vec>) -> bool { for rule in rules { match rule.is_valid() { Ok(_) => { - valid_rules.insert(Arc::clone(&rule)); + valid_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[Flow load_rules] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -193,7 +191,7 @@ pub fn load_rules(rules: Vec>) -> bool { ), } } - if valid_rules.len() > 0 { + if !valid_rules.is_empty() { valid_rules_map.insert(res.clone(), valid_rules); } } @@ -210,7 +208,7 @@ pub fn load_rules(rules: Vec>) -> bool { rules, controller_map.get_mut(res).unwrap_or(&mut placeholder), ); - if new_tcs_of_res.len() > 0 { + if !new_tcs_of_res.is_empty() { valid_controller_map.insert(res.clone(), new_tcs_of_res); } } @@ -223,7 +221,7 @@ pub fn load_rules(rules: Vec>) -> bool { utils::curr_time_nanos() - start ); log_rule_update(&valid_rules_map); - return true; + true } /// `load_rules_of_resource` loads the given resource's flow rules to the rule manager, while all previous resource's rules will be replaced. @@ -231,14 +229,14 @@ pub fn load_rules(rules: Vec>) -> bool { // This func acquires locks on global `RULE_MAP` and `CONTROLLER_MAP`, // please release your locks on them before calling this func pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - if res.len() == 0 { + if res.is_empty() { return Err(Error::msg("empty resource")); } let rules: HashSet<_> = rules.into_iter().collect(); let mut global_rule_map = RULE_MAP.lock().unwrap(); let mut global_controller_map = CONTROLLER_MAP.lock().unwrap(); // clear resource rules - if rules.len() == 0 { + if rules.is_empty() { global_rule_map.remove(res); global_controller_map.remove(res); logging::info!("[Flow] clear resource level rules, resource {}", res); @@ -254,7 +252,7 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - valid_res_rules.insert(Arc::clone(&rule)); + valid_res_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[Flow load_rules_of_resource] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -266,15 +264,14 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result, old_res_tcs: &Vec>) -> (usize, usize) { +fn calculate_reuse_index_for(r: &Arc, old_res_tcs: &[Arc]) -> (usize, usize) { // the index of equivalent rule in old traffic shaping controller slice let mut eq_idx = usize::MAX; // the index of statistic reusable rule in old traffic shaping controller slice @@ -489,7 +486,7 @@ pub fn build_resource_traffic_shaping_controller( logging::error!("unmatched resource name expect: {}, actual: {}. Unmatched resource name in flow::build_resource_traffic_shaping_controller(), rule: {:?}", res, rule.resource, rule); continue; } - let (eq_idx, reuse_stat_idx) = calculate_reuse_index_for(&rule, old_res_tcs); + let (eq_idx, reuse_stat_idx) = calculate_reuse_index_for(rule, old_res_tcs); // First check equals scenario if eq_idx != usize::MAX { @@ -502,10 +499,7 @@ pub fn build_resource_traffic_shaping_controller( } let gen_fun_map = GEN_FUN_MAP.read().unwrap(); - let key = ControllerGenKey::new( - rule.calculate_strategy.clone(), - rule.control_strategy.clone(), - ); + let key = ControllerGenKey::new(rule.calculate_strategy, rule.control_strategy); let generator = gen_fun_map.get(&key); if generator.is_none() { @@ -517,11 +511,11 @@ pub fn build_resource_traffic_shaping_controller( let tc = { if reuse_stat_idx != usize::MAX { generator( - Arc::clone(&rule), + Arc::clone(rule), Some(Arc::clone(old_res_tcs[reuse_stat_idx].stat())), ) } else { - generator(Arc::clone(&rule), None) + generator(Arc::clone(rule), None) } }; @@ -606,7 +600,7 @@ mod test { let controller_map = CONTROLLER_MAP.lock().unwrap(); assert!(GEN_FUN_MAP.read().unwrap().contains_key(&key)); - assert!(controller_map[&resource].len() > 0); + assert!(!controller_map[&resource].is_empty()); remove_traffic_shaping_generator( CalculateStrategy::Custom(STRATEGY), ControlStrategy::Custom(STRATEGY), @@ -638,7 +632,7 @@ mod test { load_rules(vec![Arc::clone(&r1), Arc::clone(&r2)]); let rs = get_rules(); - if rs[0].resource == String::from("abc1") { + if rs[0].resource == *"abc1" { // Arc equals when inner T equals, even if they are different pointers assert_eq!(rs[0], r1); assert_eq!(rs[1], r2); @@ -670,7 +664,7 @@ mod test { load_rules(vec![r1.clone(), r2.clone()]); let rs = get_rules(); - if rs[0].resource == String::from("abc1") { + if rs[0].resource == *"abc1" { // Arc equals when inner T equals, even if they are different pointers assert_eq!(rs[0], r1); assert_eq!(rs[1], r2); @@ -682,7 +676,7 @@ mod test { let controller_map = CONTROLLER_MAP.lock().unwrap(); assert_eq!(1, controller_map["abc2"].len()); - assert_eq!(false, controller_map["abc2"][0].stat().reuse_global()); + assert!(!controller_map["abc2"][0].stat().reuse_global()); assert!(Arc::ptr_eq( controller_map["abc2"][0].stat().read_only_metric(), @@ -782,7 +776,7 @@ mod test { 0, controller_map .entry(String::from("abc1")) - .or_insert(Vec::new()) + .or_default() .len() ); @@ -864,35 +858,35 @@ mod test { let fake_tc0 = Arc::new(Controller::new(Arc::clone(&r0), s0)); let stat0 = fake_tc0.stat(); assert!(Arc::ptr_eq(&NOP_STAT, stat0)); - assert_eq!(false, stat0.reuse_global()); + assert!(!stat0.reuse_global()); assert!(stat0.write_only_metric().is_some()); let s1 = generate_stat_for(&r1).unwrap(); let fake_tc1 = Arc::new(Controller::new(Arc::clone(&r1), s1)); let stat1 = fake_tc1.stat(); assert!(!Arc::ptr_eq(&NOP_STAT, stat1)); - assert_eq!(true, stat1.reuse_global()); + assert!(stat1.reuse_global()); assert!(stat1.write_only_metric().is_none()); let s2 = generate_stat_for(&r2).unwrap(); let fake_tc2 = Arc::new(Controller::new(Arc::clone(&r2), s2)); let stat2 = fake_tc2.stat(); assert!(!Arc::ptr_eq(&NOP_STAT, stat2)); - assert_eq!(true, stat2.reuse_global()); + assert!(stat2.reuse_global()); assert!(stat2.write_only_metric().is_none()); let s3 = generate_stat_for(&r3).unwrap(); let fake_tc3 = Arc::new(Controller::new(Arc::clone(&r3), s3)); let stat3 = fake_tc3.stat(); assert!(!Arc::ptr_eq(&NOP_STAT, stat3)); - assert_eq!(true, stat3.reuse_global()); + assert!(stat3.reuse_global()); assert!(stat3.write_only_metric().is_none()); let s4 = generate_stat_for(&r4).unwrap(); let fake_tc4 = Arc::new(Controller::new(Arc::clone(&r4), s4)); let stat4 = fake_tc4.stat(); assert!(!Arc::ptr_eq(&NOP_STAT, stat4)); - assert_eq!(false, stat4.reuse_global()); + assert!(!stat4.reuse_global()); assert!(stat4.write_only_metric().is_some()); let mut controller_map = CONTROLLER_MAP.lock().unwrap(); @@ -1004,7 +998,7 @@ mod test { ..Default::default() }); - load_rules(vec![r11.clone(), r12.clone(), r21.clone(), r22.clone()]); + load_rules(vec![r11.clone(), r12.clone(), r21, r22]); let result = load_rules_of_resource(&String::from(""), vec![r11.clone(), r12.clone()]); assert!(result.is_err()); diff --git a/sentinel-core/src/core/flow/traffic_shaping/adaptive.rs b/sentinel-core/src/core/flow/traffic_shaping/adaptive.rs index f7a8901..d887238 100644 --- a/sentinel-core/src/core/flow/traffic_shaping/adaptive.rs +++ b/sentinel-core/src/core/flow/traffic_shaping/adaptive.rs @@ -5,7 +5,7 @@ //! - If the water_mark is less than Rule.mem_low_water_mark, the threshold is Rule.low_mem_usage_threshold. //! - If the water_mark is greater than Rule.mem_high_water_mark, the threshold is Rule.high_mem_usage_threshold. //! - Otherwise, the threshold is `((water_mark - mem_low_water_mark)/(mem_high_water_mark - mem_low_water_mark)) * -//! (high_mem_usage_threshold - low_mem_usage_threshold) + low_mem_usage_threshold`. +//! (high_mem_usage_threshold - low_mem_usage_threshold) + low_mem_usage_threshold`. //! use super::Rule; diff --git a/sentinel-core/src/core/flow/traffic_shaping/throttling.rs b/sentinel-core/src/core/flow/traffic_shaping/throttling.rs index c4a785b..bca04af 100644 --- a/sentinel-core/src/core/flow/traffic_shaping/throttling.rs +++ b/sentinel-core/src/core/flow/traffic_shaping/throttling.rs @@ -10,7 +10,7 @@ use std::sync::{ Arc, Weak, }; -static BLOCK_MSG_QUEUEING: &'static str = "flow throttling check blocked, threshold is <= 0.0"; +static BLOCK_MSG_QUEUEING: &str = "flow throttling check blocked, threshold is <= 0.0"; #[derive(Debug)] pub struct ThrottlingChecker { @@ -97,8 +97,8 @@ impl Checker for ThrottlingChecker { // Expected pass time of this request. let expected_time = loaded_last_passed_time + interval_ns; // It has been more than `interval_ns` not running this task - if expected_time <= curr_nano { - if self + if expected_time <= curr_nano + && self .last_passed_time .compare_exchange( loaded_last_passed_time, @@ -107,9 +107,8 @@ impl Checker for ThrottlingChecker { Ordering::Relaxed, ) .is_ok() - { - return TokenResult::new_pass(); - } + { + return TokenResult::new_pass(); } // It has been run recently, need queueing, check queueing time let estimated_queue_duration = @@ -160,9 +159,9 @@ impl Checker for ThrottlingChecker { } } if estimated_queue_duration > 0 { - return TokenResult::new_should_wait(estimated_queue_duration.try_into().unwrap()); + TokenResult::new_should_wait(estimated_queue_duration.try_into().unwrap()) } else { - return TokenResult::new_should_wait(0); + TokenResult::new_should_wait(0) } } } @@ -236,14 +235,14 @@ mod test { const EPSILON: f64 = 2.0; // wait_count is count of request that will wait and not be blocked let wait_count: u64 = timeout_ms as u64 / (interval_ms as f64 / threshold) as u64; - for i in 0..wait_count as usize { - assert!(result_list[i].is_wait()); - let wt = result_list[i].nanos_to_wait() as f64; + for (i, result) in result_list.iter().enumerate().take(wait_count as usize) { + assert!(result.is_wait()); + let wt = result.nanos_to_wait() as f64; let mid = ((i + 1) as u64 * 1000 * unix_time_unit_offset() / wait_count) as f64; assert!(wt > (1.0 - EPSILON) * mid && wt < (1.0 + EPSILON) * mid); } - for i in wait_count as usize..req_count { - assert!(result_list[i].is_blocked()); + for result in result_list.iter().take(req_count).skip(wait_count as usize) { + assert!(result.is_blocked()); } } diff --git a/sentinel-core/src/core/hotspot/cache.rs b/sentinel-core/src/core/hotspot/cache.rs index 63edcc9..5b16985 100644 --- a/sentinel-core/src/core/hotspot/cache.rs +++ b/sentinel-core/src/core/hotspot/cache.rs @@ -44,6 +44,7 @@ pub trait CounterTrait: Send + Sync + std::fmt::Debug + Default + Q: Hash + Eq + 'static + Sized; fn keys(&self) -> Vec; fn len(&self) -> usize; + fn is_empty(&self) -> bool; fn purge(&self); } @@ -86,7 +87,7 @@ where fn add_if_absent(&self, key: K, value: u64) -> Option> { let mut cache = self.cache.write().unwrap(); if cache.contains(&key) { - cache.get(&key).map(|v| Arc::clone(v)) + cache.get(&key).map(Arc::clone) } else { cache.put(key, Arc::new(AtomicU64::new(value))); None @@ -99,7 +100,7 @@ where KeyRef: Borrow, Q: Hash + Eq + ?Sized, { - self.cache.write().unwrap().get(&key).map(|v| Arc::clone(v)) + self.cache.write().unwrap().get(key).map(Arc::clone) } // `remove` removes a key from the cache. @@ -109,7 +110,7 @@ where KeyRef: Borrow, Q: Hash + Eq + ?Sized, { - self.cache.write().unwrap().pop(&key).is_some() + self.cache.write().unwrap().pop(key).is_some() } // `contains` checks if a key exists in cache @@ -119,7 +120,7 @@ where KeyRef: Borrow, Q: Hash + Eq + ?Sized, { - self.cache.read().unwrap().contains(&key) + self.cache.read().unwrap().contains(key) } // `keys` returns the keys in the cache, from oldest to newest. @@ -134,6 +135,10 @@ where self.cache.read().unwrap().len() } + fn is_empty(&self) -> bool { + self.len() == 0 + } + // `purge` clears all cache entries. fn purge(&self) { self.cache.write().unwrap().clear() @@ -186,6 +191,7 @@ pub(crate) mod test { Q: Hash + Eq + Sized + 'static; fn keys(&self) -> Vec; fn len(&self) -> usize; + fn is_empty(&self) -> bool; fn purge(&self); } } diff --git a/sentinel-core/src/core/hotspot/rule.rs b/sentinel-core/src/core/hotspot/rule.rs index a44e169..4c43c0f 100644 --- a/sentinel-core/src/core/hotspot/rule.rs +++ b/sentinel-core/src/core/hotspot/rule.rs @@ -64,9 +64,9 @@ pub struct Rule { pub resource: String, /// `metric_type` indicates the metric type for checking logic. /// For Concurrency metric, hotspot module will check the each hot parameter's concurrency, - /// if concurrency exceeds the threshold, reject the traffic directly. + /// if concurrency exceeds the threshold, reject the traffic directly. /// For QPS metric, hotspot module will check the each hot parameter's QPS, - /// the `control_strategy` decides the behavior of traffic shaping controller + /// the `control_strategy` decides the behavior of traffic shaping controller pub metric_type: MetricType, /// `control_strategy` indicates the traffic shaping behaviour. /// `control_strategy` only takes effect when `metric_type` is QPS @@ -141,13 +141,13 @@ impl SentinelRule for Rule { } fn is_valid(&self) -> crate::Result<()> { - if self.resource.len() == 0 { + if self.resource.is_empty() { return Err(Error::msg("empty resource name")); } if self.metric_type == MetricType::QPS && self.duration_in_sec == 0 { return Err(Error::msg("invalid duration")); } - if self.param_index > 0 && self.param_key.len() != 0 { + if self.param_index > 0 && !self.param_key.is_empty() { return Err(Error::msg( "param index and param key are mutually exclusive", )); @@ -236,7 +236,6 @@ mod test { duration_in_sec: 1, params_max_capacity: 10000, specific_items: specific_items.clone(), - ..Default::default() }; let rule2 = Rule { id: "abc".into(), @@ -251,7 +250,6 @@ mod test { duration_in_sec: 1, params_max_capacity: 10000, specific_items, - ..Default::default() }; assert_eq!(rule1, rule2); } diff --git a/sentinel-core/src/core/hotspot/rule_manager.rs b/sentinel-core/src/core/hotspot/rule_manager.rs index 7f6bf6d..7416b1f 100644 --- a/sentinel-core/src/core/hotspot/rule_manager.rs +++ b/sentinel-core/src/core/hotspot/rule_manager.rs @@ -85,7 +85,7 @@ pub fn get_traffic_controller_list_for(res: &String) -> Vec> { } fn log_rule_update(map: &RuleMap) { - if map.len() == 0 { + if map.is_empty() { logging::info!("[HotspotRuleManager] Hotspot param flow rules were cleared") } else { logging::info!( @@ -111,7 +111,7 @@ pub fn append_rule(rule: Arc) -> bool { .lock() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(Arc::clone(&rule)); } Err(err) => logging::warn!( @@ -130,12 +130,12 @@ pub fn append_rule(rule: Arc) -> bool { .get_mut(&rule.resource) .unwrap_or(&mut placeholder), ); - if new_tcs_of_res.len() > 0 { + if !new_tcs_of_res.is_empty() { CONTROLLER_MAP .write() .unwrap() .entry(rule.resource.clone()) - .or_insert(Vec::new()) + .or_default() .push(Arc::clone(&new_tcs_of_res[0])); } true @@ -148,14 +148,12 @@ pub fn append_rule(rule: Arc) -> bool { pub fn load_rules(rules: Vec>) -> bool { let mut rule_map: RuleMap = HashMap::new(); for rule in rules { - let entry = rule_map - .entry(rule.resource.clone()) - .or_insert(HashSet::new()); + let entry = rule_map.entry(rule.resource.clone()).or_default(); entry.insert(rule); } let mut global_rule_map = RULE_MAP.lock().unwrap(); - if &*global_rule_map == &rule_map { + if *global_rule_map == rule_map { logging::info!( "[HotSpot] Load rules is the same with current rules, so ignore load operation." ); @@ -168,7 +166,7 @@ pub fn load_rules(rules: Vec>) -> bool { let mut valid_rules = HashSet::new(); for rule in rules { match rule.is_valid() { - Ok(_) => {valid_rules.insert(Arc::clone(&rule));}, + Ok(_) => {valid_rules.insert(Arc::clone(rule));}, Err(err) => logging::warn!( "[HotSpot onRuleUpdate] Ignoring invalid hotspot param flow rule {:?}, reason: {:?}", rule, @@ -176,7 +174,7 @@ pub fn load_rules(rules: Vec>) -> bool { ), } } - if valid_rules.len() > 0 { + if !valid_rules.is_empty() { valid_rules_map.insert(res.clone(), valid_rules); } } @@ -190,10 +188,10 @@ pub fn load_rules(rules: Vec>) -> bool { let mut placeholder = Vec::new(); let new_tcs_of_res = build_resource_traffic_shaping_controller( res, - &rules, + rules, controller_map.get_mut(res).unwrap_or(&mut placeholder), ); - if new_tcs_of_res.len() > 0 { + if !new_tcs_of_res.is_empty() { valid_controller_map.insert(res.clone(), new_tcs_of_res); } } @@ -207,7 +205,7 @@ pub fn load_rules(rules: Vec>) -> bool { ); log_rule_update(&valid_rules_map); - return true; + true } /// `load_rules_of_resource` loads the given resource's flow rules to the rule manager, while all previous resource's rules will be replaced. @@ -215,14 +213,14 @@ pub fn load_rules(rules: Vec>) -> bool { // This func acquires locks on global `RULE_MAP` and `CONTROLLER_MAP`, // please release your locks on them before calling this func pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - if res.len() == 0 { + if res.is_empty() { return Err(Error::msg("empty resource")); } let rules: HashSet<_> = rules.into_iter().collect(); let mut global_rule_map = RULE_MAP.lock().unwrap(); let mut global_controller_map = CONTROLLER_MAP.write().unwrap(); // clear resource rules - if rules.len() == 0 { + if rules.is_empty() { global_rule_map.remove(res); global_controller_map.remove(res); logging::info!("[HotSpot] clear resource level rules, resource {}", res); @@ -238,7 +236,7 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - valid_res_rules.insert(Arc::clone(&rule)); + valid_res_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[HotSpot load_rules_of_resource] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -250,15 +248,14 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result Re } } -fn calculate_reuse_index_for(r: &Arc, old_res_tcs: &Vec>) -> (usize, usize) { +fn calculate_reuse_index_for(r: &Arc, old_res_tcs: &[Arc]) -> (usize, usize) { // the index of equivalent rule in old traffic shaping controller slice let mut eq_idx = usize::MAX; // the index of statistic reusable rule in old traffic shaping controller slice @@ -392,7 +389,7 @@ pub fn build_resource_traffic_shaping_controller( logging::error!("unmatched resource name expect: {}, actual: {}. Unmatched resource name in flow::build_resource_traffic_shaping_controller(), rule: {:?}", res, rule.resource, rule); continue; } - let (eq_idx, reuse_stat_idx) = calculate_reuse_index_for(&rule, old_res_tcs); + let (eq_idx, reuse_stat_idx) = calculate_reuse_index_for(rule, old_res_tcs); // First check equals scenario if eq_idx != usize::MAX { @@ -416,11 +413,11 @@ pub fn build_resource_traffic_shaping_controller( let tc = { if reuse_stat_idx != usize::MAX { generator( - Arc::clone(&rule), + Arc::clone(rule), Some(Arc::clone(old_res_tcs[reuse_stat_idx].metric())), ) } else { - generator(Arc::clone(&rule), None) + generator(Arc::clone(rule), None) } }; @@ -658,7 +655,7 @@ mod test { threshold: 200, duration_in_sec: 1, burst_count: 10, - specific_items: specific_items, + specific_items, ..Default::default() }); diff --git a/sentinel-core/src/core/hotspot/traffic_shaping/mod.rs b/sentinel-core/src/core/hotspot/traffic_shaping/mod.rs index f856285..c41fc55 100644 --- a/sentinel-core/src/core/hotspot/traffic_shaping/mod.rs +++ b/sentinel-core/src/core/hotspot/traffic_shaping/mod.rs @@ -134,15 +134,15 @@ where } }; if concurrency <= threshold { - return TokenResult::new_pass(); + TokenResult::new_pass() } else { let msg = format!("hotspot specific concurrency check blocked, arg: {:?}", arg); - return TokenResult::new_blocked_with_cause( + TokenResult::new_blocked_with_cause( BlockType::HotSpotParamFlow, msg, self.rule.clone(), Arc::new(concurrency), - ); + ) } } @@ -150,10 +150,8 @@ where pub fn extract_args(&self, ctx: &EntryContext) -> Option { if let Some(args) = self.extract_kv_args(ctx) { Some(args) - } else if let Some(args) = self.extract_list_args(ctx) { - Some(args) } else { - None + self.extract_list_args(ctx) } } @@ -163,7 +161,7 @@ where Some(args) => { let mut idx = self.rule.param_index; if idx < 0 { - idx = args.len() as isize + idx; + idx += args.len() as isize; } if idx < 0 { logging::debug!("[extract_args] The param index of hotspot traffic shaping controller is invalid, args: {:?}, param_index: {}", args, self.param_index()); @@ -187,7 +185,7 @@ where match attachments { Some(attachments) => { let key = self.rule.param_key.trim(); - if key.len() == 0 { + if key.is_empty() { logging::debug!( "[extract_args] The param key is invalid, key: {}", self.rule.param_key @@ -325,9 +323,7 @@ pub(crate) mod test { }); let controller = gen_reject::(rule, None); - let mut args = ParamsList::new(); - args.push("1".into()); - args.push("2".into()); + let args = vec!["1".into(), "2".into()]; let mut attachments = ParamsMap::new(); attachments.insert("test1".into(), "v1".into()); @@ -354,9 +350,7 @@ pub(crate) mod test { }); let controller = gen_reject::(rule, None); - let mut args = ParamsList::new(); - args.push("1".into()); - args.push("2".into()); + let args = vec!["1".into(), "2".into()]; let mut attachments = ParamsMap::new(); attachments.insert("test1".into(), "v1".into()); @@ -383,9 +377,7 @@ pub(crate) mod test { }); let controller = gen_reject::(rule, None); - let mut args = ParamsList::new(); - args.push("1".into()); - args.push("2".into()); + let args = vec!["1".into(), "2".into()]; let mut attachments = ParamsMap::new(); attachments.insert("test1".into(), "v1".into()); @@ -412,9 +404,7 @@ pub(crate) mod test { }); let controller = gen_reject::(rule, None); - let mut args = ParamsList::new(); - args.push("1".into()); - args.push("2".into()); + let args = vec!["1".into(), "2".into()]; let mut attachments = ParamsMap::new(); attachments.insert("test1".into(), "v1".into()); @@ -539,10 +529,10 @@ pub(crate) mod test { }); let controller = gen_reject(rule, Some(metric)); - let token = controller.perform_checking(010110.to_string(), 130); + let token = controller.perform_checking(10110.to_string(), 130); assert!(token.is_blocked()); - let token = controller.perform_checking(010110.to_string(), 20); + let token = controller.perform_checking(10110.to_string(), 20); assert!(token.is_pass()); } @@ -585,7 +575,7 @@ pub(crate) mod test { }); let controller = gen_reject(rule, Some(metric)); - let token = controller.perform_checking(010110.to_string(), 20); + let token = controller.perform_checking(10110.to_string(), 20); assert!(token.is_pass()); assert_eq!(30, old_qps.load(Ordering::SeqCst)); } @@ -629,7 +619,7 @@ pub(crate) mod test { let controller = gen_reject(rule, Some(metric)); utils::sleep_for_ms(10); - let token = controller.perform_checking(010110.to_string(), 20); + let token = controller.perform_checking(10110.to_string(), 20); assert!(token.is_pass()); assert!(last_add_token_time.load(Ordering::SeqCst) > curr_time); } @@ -674,7 +664,7 @@ pub(crate) mod test { let controller = gen_reject(rule, Some(metric)); utils::sleep_for_ms(10); - let token = controller.perform_checking(010110.to_string(), 20); + let token = controller.perform_checking(10110.to_string(), 20); assert!(token.is_pass()); assert!(last_add_token_time.load(Ordering::SeqCst) > curr_time); assert!(old_qps.load(Ordering::SeqCst) > 30); @@ -713,7 +703,7 @@ pub(crate) mod test { ..Default::default() }); let controller = gen_throttling(rule, Some(metric)); - let token = controller.perform_checking(010110.to_string(), 20); + let token = controller.perform_checking(10110.to_string(), 20); assert!(token.is_pass()); } } diff --git a/sentinel-core/src/core/hotspot/traffic_shaping/reject.rs b/sentinel-core/src/core/hotspot/traffic_shaping/reject.rs index 0c6c33e..40a9239 100644 --- a/sentinel-core/src/core/hotspot/traffic_shaping/reject.rs +++ b/sentinel-core/src/core/hotspot/traffic_shaping/reject.rs @@ -18,6 +18,12 @@ impl RejectChecker { } } +impl Default for RejectChecker { + fn default() -> Self { + Self::new() + } +} + impl Checker for RejectChecker { fn get_owner(&self) -> &Weak> { &self.owner @@ -66,7 +72,7 @@ impl Checker for RejectChecker { if last_add_token_time_arc.is_none() { // First fill token, and consume token immediately let left_count = max_count - batch_count as u64; - token_counter.add_if_absent(arg.clone(), left_count); + token_counter.add_if_absent(arg, left_count); return TokenResult::new_pass(); } let last_add_token_time_arc = last_add_token_time_arc.unwrap(); diff --git a/sentinel-core/src/core/hotspot/traffic_shaping/throttling.rs b/sentinel-core/src/core/hotspot/traffic_shaping/throttling.rs index 9e77dff..3bccbe3 100644 --- a/sentinel-core/src/core/hotspot/traffic_shaping/throttling.rs +++ b/sentinel-core/src/core/hotspot/traffic_shaping/throttling.rs @@ -13,6 +13,12 @@ pub struct ThrottlingChecker { owner: Weak>, } +impl Default for ThrottlingChecker { + fn default() -> Self { + Self::new() + } +} + impl ThrottlingChecker { pub fn new() -> Self { ThrottlingChecker { owner: Weak::new() } diff --git a/sentinel-core/src/core/isolation/rule.rs b/sentinel-core/src/core/isolation/rule.rs index 0797cec..fd031a5 100644 --- a/sentinel-core/src/core/isolation/rule.rs +++ b/sentinel-core/src/core/isolation/rule.rs @@ -81,7 +81,7 @@ impl SentinelRule for Rule { } fn is_valid(&self) -> crate::Result<()> { - if self.resource.len() == 0 { + if self.resource.is_empty() { return Err(Error::msg("empty resource of isolation rule")); } diff --git a/sentinel-core/src/core/isolation/rule_manager.rs b/sentinel-core/src/core/isolation/rule_manager.rs index c17e539..968f23d 100644 --- a/sentinel-core/src/core/isolation/rule_manager.rs +++ b/sentinel-core/src/core/isolation/rule_manager.rs @@ -28,11 +28,11 @@ pub fn get_rules() -> Vec> { // This func acquires a read lock on global `RULE_MAP`, // please release the lock before calling this func pub fn get_rules_of_resource(res: &String) -> Vec> { - let mut placeholder = HashSet::new(); + let placeholder = HashSet::new(); let rule_map = RULE_MAP.read().unwrap(); - let res_rules = rule_map.get(res).unwrap_or(&mut placeholder); - let rules = res_rules.clone().into_iter().collect(); - rules + let res_rules = rule_map.get(res).unwrap_or(&placeholder); + + res_rules.clone().into_iter().collect() } pub fn append_rule(rule: Arc) -> bool { @@ -52,13 +52,13 @@ pub fn append_rule(rule: Arc) -> bool { .write() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(Arc::clone(&rule)); CURRENT_RULES .lock() .unwrap() .entry(rule.resource.clone()) - .or_insert(HashSet::new()) + .or_default() .insert(rule); } Err(err) => logging::warn!( @@ -76,13 +76,11 @@ pub fn append_rule(rule: Arc) -> bool { pub fn load_rules(rules: Vec>) { let mut res_rules_map = RuleMap::new(); for rule in rules { - let val = res_rules_map - .entry(rule.resource.clone()) - .or_insert(HashSet::new()); + let val = res_rules_map.entry(rule.resource.clone()).or_default(); val.insert(rule); } let mut current_rules = CURRENT_RULES.lock().unwrap(); - if &*current_rules == &res_rules_map { + if *current_rules == res_rules_map { logging::info!( "[Isolation] Load rules is the same with current rules, so ignore load operation." ); @@ -97,7 +95,7 @@ pub fn load_rules(rules: Vec>) { for rule in rules { match rule.is_valid() { Ok(_) => { - valid_res_rules.insert(Arc::clone(&rule)); + valid_res_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[Isolation load_rules] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -106,7 +104,7 @@ pub fn load_rules(rules: Vec>) { ), } } - if valid_res_rules.len() > 0 { + if !valid_res_rules.is_empty() { valid_res_rule_map.insert(res.clone(), valid_res_rules); } } @@ -130,12 +128,12 @@ pub fn load_rules(rules: Vec>) { // This func acquires the locks on global `CURRENT_RULES` and `RULE_MAP`, // please release the locks before calling this func pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - if res.len() == 0 { + if res.is_empty() { return Err(Error::msg("empty resource")); } let rules: HashSet<_> = rules.into_iter().collect(); - if rules.len() == 0 { + if rules.is_empty() { clear_rules_of_resource(res); logging::info!("[Isolation] clear resource level rules, resource {}", res); return Ok(true); @@ -160,7 +158,7 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result { - valid_res_rules.insert(Arc::clone(&rule)); + valid_res_rules.insert(Arc::clone(rule)); } Err(err) => logging::warn!( "[Isolation load_rules_of_resource] Ignoring invalid flow rule {:?}, reason: {:?}", @@ -172,7 +170,7 @@ pub fn load_rules_of_resource(res: &String, rules: Vec>) -> Result>) -> Result TokenResult { let res_name = ctx.resource().name().clone(); - if res_name.len() == 0 { + if res_name.is_empty() { return ctx.result().clone(); } let (passed, rule, snapshot) = can_pass_check(ctx, &res_name); @@ -58,5 +58,5 @@ fn can_pass_check( } } } - return (true, None, None); + (true, None, None) } diff --git a/sentinel-core/src/core/log/metric/aggregator.rs b/sentinel-core/src/core/log/metric/aggregator.rs index 2ce577f..b68f5d1 100644 --- a/sentinel-core/src/core/log/metric/aggregator.rs +++ b/sentinel-core/src/core/log/metric/aggregator.rs @@ -49,7 +49,7 @@ pub fn write_task(mut map: MetricTimeMap) { let writer = METRIC_WRITER.as_ref().unwrap(); let mut writer = writer.lock().unwrap(); for k in keys { - writer.write(k, &mut *map.entry(k).or_insert(Vec::new())).unwrap_or_else(|err|{ + writer.write(k, &mut *map.entry(k).or_default()).unwrap_or_else(|err|{ logging::error!("[MetricAggregatorTask] fail to write metric in aggregator::write_task(). Error: {:?}",err);}); } } @@ -80,7 +80,7 @@ pub fn do_aggregate() { println!("Store last fetch time {}", cur_time); - if map.len() > 0 { + if !map.is_empty() { std::thread::spawn(move || write_task(map)); } } @@ -93,26 +93,26 @@ fn aggregate_into_map( for (t, mut item) in metrics { item.resource = node.res_name.clone(); item.resource_type = node.resource_type; - if mm.contains_key(&t) { - mm.entry(t).or_insert(Vec::new()).push(item); + if let std::collections::hash_map::Entry::Vacant(e) = mm.entry(t) { + e.insert(vec![item]); } else { - mm.insert(t, vec![item]); + mm.entry(t).or_default().push(item); } } } fn is_active_metric_item(item: &MetricItem) -> bool { - return item.pass_qps > 0 + item.pass_qps > 0 || item.block_qps > 0 || item.complete_qps > 0 || item.error_qps > 0 || item.avg_rt > 0 - || item.concurrency > 0; + || item.concurrency > 0 } fn is_item_time_stamp_in_time(ts: u64, current_sec_start: u64) -> bool { // The bucket should satisfy: windowStart between [LAST_FETCH_TIME, current_sec_start) - return ts >= LAST_FETCH_TIME.load(Ordering::SeqCst) && ts < current_sec_start; + ts >= LAST_FETCH_TIME.load(Ordering::SeqCst) && ts < current_sec_start } fn current_metric_items( @@ -120,7 +120,7 @@ fn current_metric_items( current_time: u64, ) -> HashMap { let items = retriever.metrics_on_condition(&move |ts: u64| -> bool { - return is_item_time_stamp_in_time(ts, current_time); + is_item_time_stamp_in_time(ts, current_time) }); let mut m = HashMap::with_capacity(items.len()); for item in items { @@ -129,5 +129,5 @@ fn current_metric_items( } m.insert(item.timestamp, item); } - return m; + m } diff --git a/sentinel-core/src/core/log/metric/mod.rs b/sentinel-core/src/core/log/metric/mod.rs index b5e4bbb..cb857ca 100644 --- a/sentinel-core/src/core/log/metric/mod.rs +++ b/sentinel-core/src/core/log/metric/mod.rs @@ -19,15 +19,15 @@ use std::fs; use std::path::{Path, PathBuf}; // METRIC_FILENAME_SUFFIX represents the suffix of the metric file. -static METRIC_FILENAME_SUFFIX: &'static str = "metrics.log"; +static METRIC_FILENAME_SUFFIX: &str = "metrics.log"; // METRIC_IDX_SUFFIX represents the suffix of the metric index file. -static METRIC_IDX_SUFFIX: &'static str = ".idx"; +static METRIC_IDX_SUFFIX: &str = ".idx"; // FILE_LOCK_SUFFIX represents the suffix of the lock file. -static FILE_LOCK_SUFFIX: &'static str = ".lck"; +static FILE_LOCK_SUFFIX: &str = ".lck"; // FILE_PID_PREFIX represents the pid flag of filename. -static FILE_PID_PREFIX: &'static str = "pid"; +static FILE_PID_PREFIX: &str = "pid"; -static METRIC_FILE_PATTERN: &'static str = r"\.[0-9]{4}-[0-9]{2}-[0-9]{2}(\.[0-9]*)?"; +static METRIC_FILE_PATTERN: &str = r"\.[0-9]{4}-[0-9]{2}-[0-9]{2}(\.[0-9]*)?"; type MetricItemVec = Vec; type MetricTimeMap = HashMap; @@ -46,7 +46,7 @@ pub trait MetricSearcher { fn find_by_time_and_resource( begin_time_ms: u64, end_time_ms: u64, - resource: &String, + resource: &str, ) -> Result; fn find_from_time_with_max_lines(begin_time_ms: u64, max_lines: u32) -> Result; } @@ -83,7 +83,7 @@ fn filename_matches(filename: &str, base_filename: &str) -> bool { fn list_metric_files_conditional( base_dir: &PathBuf, - file_pattern: &PathBuf, + file_pattern: &Path, predicate: fn(&str, &str) -> bool, ) -> Result> { let dir = fs::read_dir(base_dir)?; @@ -113,17 +113,18 @@ fn list_metric_files_conditional( /// List metrics files according to `base_dir` (the directory of metrics files) and /// `file_pattern` (metric file pattern). -fn list_metric_files(base_dir: &PathBuf, file_pattern: &PathBuf) -> Result> { - return list_metric_files_conditional(base_dir, file_pattern, filename_matches); +fn list_metric_files(base_dir: &PathBuf, file_pattern: &Path) -> Result> { + list_metric_files_conditional(base_dir, file_pattern, filename_matches) } /// Sort the metric files by their date time. /// This function is used to remove the deprecated files, or create a new file in order. +#[allow(clippy::ptr_arg)] fn filename_comparator(file1: &PathBuf, file2: &PathBuf) -> Ordering { let name1 = file1.file_name().unwrap().to_str().unwrap(); let name2 = file2.file_name().unwrap().to_str().unwrap(); - let a1 = name1.split(".").collect::>(); - let a2 = name2.split(".").collect::>(); + let a1 = name1.split('.').collect::>(); + let a2 = name2.split('.').collect::>(); let mut date_str1 = a1[2]; let mut date_str2 = a2[2]; @@ -135,9 +136,9 @@ fn filename_comparator(file1: &PathBuf, file2: &PathBuf) -> Ordering { // compare date first if date_str1 != date_str2 { - return date_str1.cmp(&date_str2); + return date_str1.cmp(date_str2); } // same date, compare the file number - name1.cmp(&name2) + name1.cmp(name2) } diff --git a/sentinel-core/src/core/log/metric/reader.rs b/sentinel-core/src/core/log/metric/reader.rs index 6e20304..1f88879 100644 --- a/sentinel-core/src/core/log/metric/reader.rs +++ b/sentinel-core/src/core/log/metric/reader.rs @@ -26,6 +26,7 @@ pub trait MetricLogReader { } // Not thread-safe itself, but guarded by the outside MetricSearcher. +#[derive(Default)] pub struct DefaultMetricLogReader {} impl DefaultMetricLogReader { @@ -102,7 +103,7 @@ impl DefaultMetricLogReader { } // empty resource name indicates "fetch all" - if resource.len() == 0 || resource == &item.resource { + if resource.is_empty() || resource == &item.resource { items.push(item); } @@ -127,7 +128,7 @@ impl MetricLogReader for DefaultMetricLogReader { start_offset: SeekFrom, max_lines: usize, ) -> Result { - if name_list.len() == 0 { + if name_list.is_empty() { return Ok(Vec::new()); } let mut file_no = file_no; @@ -157,7 +158,7 @@ impl MetricLogReader for DefaultMetricLogReader { } file_no += 1; } - return Ok(items); + Ok(items) } fn read_metrics_by_end_time( @@ -169,7 +170,7 @@ impl MetricLogReader for DefaultMetricLogReader { end_ms: u64, resource: String, ) -> Result { - if name_list.len() == 0 { + if name_list.is_empty() { return Ok(Vec::new()); } let mut file_no = file_no; @@ -206,12 +207,12 @@ impl MetricLogReader for DefaultMetricLogReader { } file_no += 1; } - return Ok(items); + Ok(items) } } fn get_latest_second(items: &MetricItemVec) -> u64 { - if items.len() == 0 { + if items.is_empty() { return 0; } items[items.len() - 1].timestamp / 1000 diff --git a/sentinel-core/src/core/log/metric/searcher.rs b/sentinel-core/src/core/log/metric/searcher.rs index 4003f3a..1067bad 100644 --- a/sentinel-core/src/core/log/metric/searcher.rs +++ b/sentinel-core/src/core/log/metric/searcher.rs @@ -32,10 +32,10 @@ pub struct DefaultMetricSearcher { impl DefaultMetricSearcher { pub fn new(base_dir: String, base_filename: String) -> Result { - if base_dir.len() == 0 { + if base_dir.is_empty() { return Err(Error::msg("empty base directory")); } - if base_filename.len() == 0 { + if base_filename.is_empty() { return Err(Error::msg("empty base filename pattern")); } let reader = DefaultMetricLogReader::new(); @@ -108,12 +108,12 @@ impl DefaultMetricSearcher { } } } - return Ok(Vec::new()); + Ok(Vec::new()) } fn get_offset_start_and_file_idx( &self, - filenames: &Vec, + filenames: &[PathBuf], begin_time_ms: u64, ) -> Result<(SeekFrom, usize)> { let cache_ok = self.is_position_in_time_for(begin_time_ms)?; @@ -151,17 +151,17 @@ impl DefaultMetricSearcher { let mut sec: u64; loop { let mut buffer: [u8; 8] = [0; 8]; - file.read(&mut buffer)?; + file.read_exact(&mut buffer)?; sec = u64::from_be_bytes(buffer); if sec >= begin_sec { break; } let mut buffer: [u8; 4] = [0; 4]; - file.read(&mut buffer)?; + file.read_exact(&mut buffer)?; cached_pos.cur_offset_in_idx = SeekFrom::Start(file.seek(SeekFrom::Current(0))?); } let mut buffer: [u8; 4] = [0; 4]; - file.read(&mut buffer)?; + file.read_exact(&mut buffer)?; let offset = u32::from_be_bytes(buffer); // Cache the idx filename and position cached_pos.metric_filename = filename.into(); @@ -179,10 +179,10 @@ impl DefaultMetricSearcher { if idx_filename == &PathBuf::from("") { return Ok(false); } - let mut idx_file = open_file_and_seek_to(&idx_filename, cached_pos.cur_offset_in_idx)?; + let mut idx_file = open_file_and_seek_to(idx_filename, cached_pos.cur_offset_in_idx)?; let mut buffer: [u8; 8] = [0; 8]; - idx_file.read(&mut buffer)?; + idx_file.read_exact(&mut buffer)?; let sec = u64::from_be_bytes(buffer); Ok(sec == cached_pos.cur_sec_in_idx) diff --git a/sentinel-core/src/core/log/metric/writer.rs b/sentinel-core/src/core/log/metric/writer.rs index 95cab55..f4a33a9 100644 --- a/sentinel-core/src/core/log/metric/writer.rs +++ b/sentinel-core/src/core/log/metric/writer.rs @@ -17,14 +17,14 @@ pub struct DefaultMetricLogWriter { impl MetricLogWriter for DefaultMetricLogWriter { fn write(&mut self, ts: u64, items: &mut Vec) -> Result<()> { - if items.len() == 0 { + if items.is_empty() { return Ok(()); } if ts == 0 { return Err(Error::msg(format!("Invalid timestamp: {}", ts))); } if self.cur_metric_file.is_none() || self.cur_metric_idx_file.is_none() { - return Err(Error::msg(format!("file handle not initialized"))); + return Err(Error::msg("file handle not initialized".to_string())); } // Update all metric items to the given timestamp. for item in items.iter_mut() { @@ -57,7 +57,7 @@ impl MetricLogWriter for DefaultMetricLogWriter { self.latest_op_sec = time_sec; } - return Ok(()); + Ok(()) } } @@ -67,7 +67,7 @@ impl DefaultMetricLogWriter { for item in items { // Append the LF line separator. let s = item.to_string() + "\n"; - metric_out.write(s.as_ref())?; + metric_out.write_all(s.as_ref())?; } metric_out.flush()?; Ok(()) @@ -105,8 +105,8 @@ impl DefaultMetricLogWriter { fn write_index(&self, time: u64, offset: u64) -> Result<()> { // Use BigEndian here to keep consistent with DataOutputStream in Java. let mut idx_out = self.cur_metric_idx_file.as_ref().unwrap().write().unwrap(); - idx_out.write(&time.to_be_bytes())?; - idx_out.write(&offset.to_be_bytes())?; + idx_out.write_all(&time.to_be_bytes())?; + idx_out.write_all(&offset.to_be_bytes())?; idx_out.flush()?; Ok(()) } @@ -117,8 +117,7 @@ impl DefaultMetricLogWriter { let files = list_metric_files(&self.base_dir, &self.base_filename)?; if files.len() >= self.max_file_amount { let amount_to_remove = files.len() - self.max_file_amount + 1; - for i in 0..amount_to_remove { - let filename = &files[i]; + for filename in files.iter().take(amount_to_remove) { let idx_filename = form_metric_idx_filename(filename.to_str().unwrap()); match fs::remove_file(filename) { Ok(_) => { @@ -151,14 +150,14 @@ impl DefaultMetricLogWriter { &PathBuf::from(&file_pattern), |filename: &str, p: &str| -> bool { filename.contains(p) }, )?; - if list.len() == 0 { + if list.is_empty() { return Ok(self.base_dir.to_str().unwrap().to_owned() + &file_pattern); } // Find files with the same prefix pattern, have to add the order to separate files. let last = &list[list.len() - 1]; let mut n = 0; - let items = last.to_str().unwrap().split(".").collect::>(); - if items.len() > 0 { + let items = last.to_str().unwrap().split('.').collect::>(); + if !items.is_empty() { n = str::parse::(items[items.len() - 1]).unwrap_or(0); } return Ok(format!( @@ -195,7 +194,7 @@ impl DefaultMetricLogWriter { self.cur_metric_file = Some(RwLock::new(mf)); self.cur_metric_idx_file = Some(RwLock::new(mif)); - return Ok(()); + Ok(()) } fn initialize(&mut self) -> Result<()> { @@ -207,7 +206,7 @@ impl DefaultMetricLogWriter { let ts = utils::curr_time_millis(); self.roll_to_next_file(ts)?; self.latest_op_sec = ts / 1000; - return Ok(()); + Ok(()) } fn is_new_day(&self, last_sec: u64, sec: u64) -> bool { diff --git a/sentinel-core/src/core/stat/base/bucket_leap_array.rs b/sentinel-core/src/core/stat/base/bucket_leap_array.rs index 0fc7356..ecbd09c 100644 --- a/sentinel-core/src/core/stat/base/bucket_leap_array.rs +++ b/sentinel-core/src/core/stat/base/bucket_leap_array.rs @@ -46,7 +46,7 @@ impl BucketLeapArray { } pub fn min_rt(&self) -> u64 { - let mut res = DEFAULT_STATISTIC_MAX_RT as u64; + let mut res = DEFAULT_STATISTIC_MAX_RT; let buckets = self.get_current_values(); for b in buckets { res = cmp::min(res, b.value().min_rt()); @@ -109,7 +109,7 @@ mod test { #[test] fn min_rt() { let arr = BucketLeapArray::new(SAMPLE_COUNT, INTERVAL_MS).unwrap(); - assert_eq!(arr.min_rt(), DEFAULT_STATISTIC_MAX_RT as u64); + assert_eq!(arr.min_rt(), DEFAULT_STATISTIC_MAX_RT); arr.add_count(MetricEvent::Rt, 100); assert_eq!(arr.min_rt(), 100); } diff --git a/sentinel-core/src/core/stat/base/metric_bucket.rs b/sentinel-core/src/core/stat/base/metric_bucket.rs index 875c5cf..54d00eb 100644 --- a/sentinel-core/src/core/stat/base/metric_bucket.rs +++ b/sentinel-core/src/core/stat/base/metric_bucket.rs @@ -26,7 +26,7 @@ impl MetricTrait for MetricBucket { item.store(0, Ordering::SeqCst); } self.min_rt - .store(DEFAULT_STATISTIC_MAX_RT as u64, Ordering::SeqCst); + .store(DEFAULT_STATISTIC_MAX_RT, Ordering::SeqCst); self.max_concurrency.store(0, Ordering::SeqCst); } } @@ -35,7 +35,7 @@ impl Default for MetricBucket { fn default() -> Self { MetricBucket { counter: EnumMap::default(), - min_rt: AtomicU64::new(DEFAULT_STATISTIC_MAX_RT as u64), + min_rt: AtomicU64::new(DEFAULT_STATISTIC_MAX_RT), max_concurrency: AtomicU32::new(0), } } @@ -208,7 +208,7 @@ mod test { let mb = Arc::new(MetricBucket::new()); mb.add_rt(100); mb.reset(); - assert_eq!(mb.min_rt(), DEFAULT_STATISTIC_MAX_RT as u64); + assert_eq!(mb.min_rt(), DEFAULT_STATISTIC_MAX_RT); assert_eq!(mb.max_concurrency(), 0); } } diff --git a/sentinel-core/src/core/stat/base/sliding_window_metric.rs b/sentinel-core/src/core/stat/base/sliding_window_metric.rs index 7049c55..f34bb7a 100644 --- a/sentinel-core/src/core/stat/base/sliding_window_metric.rs +++ b/sentinel-core/src/core/stat/base/sliding_window_metric.rs @@ -81,7 +81,7 @@ impl SlidingWindowMetric { } pub fn qps_with_time(&self, now: u64, event: MetricEvent) -> f64 { - self.sum_with_time(now, event) as f64 / self.interval_s() as f64 + self.sum_with_time(now, event) as f64 / self.interval_s() } pub fn max_of_single_bucket(&self, event: MetricEvent) -> u64 { @@ -121,7 +121,7 @@ impl SlidingWindowMetric { } let mut res = Vec::new(); for (timestamp, b) in buckets_map { - if b.len() > 0 { + if !b.is_empty() { res.push(self.metric_item_from_buckets(timestamp, b)); } } @@ -361,7 +361,7 @@ mod test { for h in handles { h.join().unwrap(); } - let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr.clone()).unwrap(); + let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr).unwrap(); assert_eq!(swm.sum_with_time(now, MetricEvent::Pass), 2000); } @@ -378,7 +378,7 @@ mod test { fn min_rt() { let arr = Arc::new(BucketLeapArray::new(SAMPLE_COUNT, INTERVAL_MS).unwrap()); let (sample_count, interval_ms) = (2, 2000); - let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr.clone()).unwrap(); + let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr).unwrap(); assert!((swm.min_rt() - DEFAULT_STATISTIC_MAX_RT as f64).abs() < f64::EPSILON); } @@ -417,7 +417,7 @@ mod test { fn metric_item_from_bucket() { let arr = Arc::new(BucketLeapArray::new(SAMPLE_COUNT, INTERVAL_MS).unwrap()); let (sample_count, interval_ms, now) = (4, 2000, curr_time_millis()); - let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr.clone()).unwrap(); + let swm = SlidingWindowMetric::new(sample_count, interval_ms, arr).unwrap(); let bucket = Arc::new(BucketWrap::::new(now)); bucket.value().add_count(MetricEvent::Pass, 100); let item = swm.metric_item_from_bucket(bucket); diff --git a/sentinel-core/src/core/stat/node_storage.rs b/sentinel-core/src/core/stat/node_storage.rs index 8e7d03a..0b2e5e6 100644 --- a/sentinel-core/src/core/stat/node_storage.rs +++ b/sentinel-core/src/core/stat/node_storage.rs @@ -24,7 +24,7 @@ pub fn inbound_node() -> Arc { // resource_node_list returns the slice of all existing resource nodes. pub fn resource_node_list() -> Vec> { let res_map = RESOURCE_NODE_MAP.read().unwrap(); - res_map.values().map(|x| x.clone()).collect() + res_map.values().cloned().collect() } pub fn get_resource_node(res_name: &String) -> Option> { @@ -38,7 +38,7 @@ pub fn get_or_create_resource_node( ) -> Arc { let node = get_resource_node(res_name); match node { - Some(node) => node.clone(), + Some(node) => node, None => { if RESOURCE_NODE_MAP.read().unwrap().len() >= DEFAULT_MAX_RESOURCE_AMOUNT { logging::warn!( @@ -48,7 +48,7 @@ pub fn get_or_create_resource_node( } RESOURCE_NODE_MAP.write().unwrap().insert( res_name.clone(), - Arc::new(ResourceNode::new(res_name.clone(), resource_type.clone())), + Arc::new(ResourceNode::new(res_name.clone(), *resource_type)), ); RESOURCE_NODE_MAP .read() diff --git a/sentinel-core/src/core/stat/stat_slot.rs b/sentinel-core/src/core/stat/stat_slot.rs index 5c0b166..32f3d25 100644 --- a/sentinel-core/src/core/stat/stat_slot.rs +++ b/sentinel-core/src/core/stat/stat_slot.rs @@ -33,7 +33,7 @@ impl ResourceNodeStatSlot { fn record_complete_for(&self, node: Arc, count: u32, round_trip: u64) { // todo: cannot capture error now - node.add_count(MetricEvent::Rt, round_trip as u64); + node.add_count(MetricEvent::Rt, round_trip); node.add_count(MetricEvent::Complete, count as u64); node.decrease_concurrency(); } diff --git a/sentinel-core/src/core/system/rule_manager.rs b/sentinel-core/src/core/system/rule_manager.rs index a56ec77..3ac0a5a 100644 --- a/sentinel-core/src/core/system/rule_manager.rs +++ b/sentinel-core/src/core/system/rule_manager.rs @@ -39,8 +39,8 @@ pub fn append_rule(rule: Arc) -> bool { RULE_MAP .write() .unwrap() - .entry(rule.metric_type.clone()) - .or_insert(HashSet::new()) + .entry(rule.metric_type) + .or_default() .insert(Arc::clone(&rule)); CURRENT_RULES.lock().unwrap().push(rule); } @@ -58,7 +58,7 @@ pub fn append_rule(rule: Arc) -> bool { // please release the lock before calling this func pub fn load_rules(rules: Vec>) { let mut current_rules = CURRENT_RULES.lock().unwrap(); - if &*current_rules == &rules { + if *current_rules == rules { logging::info!( "[System] Load rules is the same with current rules, so ignore load operation." ); @@ -103,10 +103,10 @@ fn build_rule_map(rules: Vec>) -> RuleMap { ); continue; } - let value = m.entry(rule.metric_type.clone()).or_insert(HashSet::new()); + let value = m.entry(rule.metric_type).or_default(); value.insert(rule); } - return m; + m } #[cfg(test)] diff --git a/sentinel-core/src/core/system/slot.rs b/sentinel-core/src/core/system/slot.rs index 141b66a..370f26b 100644 --- a/sentinel-core/src/core/system/slot.rs +++ b/sentinel-core/src/core/system/slot.rs @@ -86,21 +86,17 @@ fn can_pass_check(rule: &Arc) -> (bool, String, Option>) { } MetricType::Load => { let l = system_metric::current_load(); - if l > threshold { - if rule.strategy != AdaptiveStrategy::BBR || !check_bbr_simple() { - res = false; - msg = "system load check blocked".into(); - } + if l > threshold && (rule.strategy != AdaptiveStrategy::BBR || !check_bbr_simple()) { + res = false; + msg = "system load check blocked".into(); } snapshot = Some(Arc::new(l) as Arc); } MetricType::CpuUsage => { let c = system_metric::current_cpu_usage() as f64; - if c > threshold { - if rule.strategy != AdaptiveStrategy::BBR || !check_bbr_simple() { - res = false; - msg = "system cpu usage check blocked".into(); - } + if c > threshold && (rule.strategy != AdaptiveStrategy::BBR || !check_bbr_simple()) { + res = false; + msg = "system cpu usage check blocked".into(); } snapshot = Some(Arc::new(c) as Arc); } @@ -113,11 +109,7 @@ fn check_bbr_simple() -> bool { let concurrency = global_inbound.current_concurrency() as f64; let min_rt = global_inbound.min_rt(); let max_complete = global_inbound.max_avg(MetricEvent::Complete); - if concurrency > 1.0 && concurrency > max_complete * min_rt / 1000.0 { - false - } else { - true - } + !(concurrency > 1.0 && concurrency > max_complete * min_rt / 1000.0) } #[cfg(test)] @@ -162,7 +154,7 @@ mod test { ..Default::default() }); let (r, _, v) = can_pass_check(&rule); - assert_eq!(true, r); + assert!(r); assert!(v.is_none()); } @@ -177,7 +169,7 @@ mod test { stat::inbound_node().increase_concurrency(); let (r, _, v) = can_pass_check(&rule); stat::inbound_node().decrease_concurrency(); - assert_eq!(false, r); + assert!(!r); assert!( (1.0 - *Arc::downcast::(v.unwrap().as_any_arc()).unwrap()).abs() < f64::EPSILON ); diff --git a/sentinel-core/src/core/system_metric.rs b/sentinel-core/src/core/system_metric.rs index 3b36d99..4dd23ed 100644 --- a/sentinel-core/src/core/system_metric.rs +++ b/sentinel-core/src/core/system_metric.rs @@ -202,7 +202,7 @@ mod test { utils::sleep_for_ms(20); }); set_cpu_usage(0.0); - assert!((current_cpu_usage() - 0.0) < f32::EPSILON); + assert!((current_cpu_usage() - 0.0).abs() < f32::EPSILON); init_cpu_collector(50); utils::sleep_for_ms(500); assert!(current_cpu_usage() > 0.0); diff --git a/sentinel-core/src/datasource/datasource/ds_consul.rs b/sentinel-core/src/datasource/adapters/ds_consul.rs similarity index 93% rename from sentinel-core/src/datasource/datasource/ds_consul.rs rename to sentinel-core/src/datasource/adapters/ds_consul.rs index e9154c9..a5c64b0 100644 --- a/sentinel-core/src/datasource/datasource/ds_consul.rs +++ b/sentinel-core/src/datasource/adapters/ds_consul.rs @@ -56,7 +56,7 @@ impl> Cons fn read_and_update(&mut self) -> Result<()> { let src = self.read_source()?; - if src.len() == 0 { + if src.is_empty() { self.get_base().update(None).unwrap(); } else { self.get_base().update(Some(&src)).unwrap(); @@ -71,16 +71,15 @@ impl> Cons .client .get(&self.property[..], Some(&self.query_options)) .unwrap(); - let kv = kv.ok_or(Error::msg(format!( - "[Consul] Cannot find the key {:?}.", - self.property - )))?; + let kv = kv.ok_or_else(|| { + Error::msg(format!("[Consul] Cannot find the key {:?}.", self.property)) + })?; self.query_options.wait_index = meta.last_index; let mut bytes = base64::decode(kv.Value).unwrap(); bytes.remove(bytes.len() - 1); bytes.remove(0); let value = String::from_utf8(bytes).unwrap(); - let value = value.replace(r#"\"#, ""); + let value = value.replace('\\', ""); Ok(value) } diff --git a/sentinel-core/src/datasource/datasource/ds_etcdv3.rs b/sentinel-core/src/datasource/adapters/ds_etcdv3.rs similarity index 84% rename from sentinel-core/src/datasource/datasource/ds_etcdv3.rs rename to sentinel-core/src/datasource/adapters/ds_etcdv3.rs index 6a98c9c..774d36f 100644 --- a/sentinel-core/src/datasource/datasource/ds_etcdv3.rs +++ b/sentinel-core/src/datasource/adapters/ds_etcdv3.rs @@ -56,7 +56,7 @@ impl> Etcd async fn read_and_update(&mut self) -> Result<()> { let src = self.read_source().await?; - if src.len() == 0 { + if src.is_empty() { self.get_base().update(None).unwrap(); } else { self.get_base().update(Some(&src)).unwrap(); @@ -73,16 +73,18 @@ impl> Etcd .range(RangeRequest::new(KeyRange::key(&self.property[..]))) .await?; let kvs = resp.take_kvs(); - if kvs.len() == 0 { + if kvs.is_empty() { return Err(Error::msg(format!( "The key {} is not existed in the etcd server.", self.property ))); } - let header = resp.take_header().ok_or(Error::msg(format!( - "The header of key {} is not existed in the etcd server", - self.property - )))?; + let header = resp.take_header().ok_or_else(|| { + Error::msg(format!( + "The header of key {} is not existed in the etcd server", + self.property + )) + })?; self.last_updated_revision = header.revision(); logging::info!( "[Etcdv3] Get the newest data for key {}, with revision {} and value {}", @@ -102,10 +104,12 @@ impl> Etcd loop { let mut inbound = self.client.watch(KeyRange::key(&self.property[..])).await?; while let Some(resp) = inbound.next().await { - let resp = resp?.ok_or(Error::msg(format!( - "Watch a None response for key {} in the etcd server", - self.property - )))?; + let resp = resp?.ok_or_else(|| { + Error::msg(format!( + "Watch a None response for key {} in the etcd server", + self.property + )) + })?; self.process_watch_response(resp).await?; } if self.closed.load(Ordering::SeqCst) { @@ -116,23 +120,25 @@ impl> Etcd } async fn process_watch_response(&mut self, mut resp: WatchResponse) -> Result<()> { - let header = resp.take_header().ok_or(Error::msg(format!( - "The header of key {} is not existed in the etcd server", - self.property - )))?; + let header = resp.take_header().ok_or_else(|| { + Error::msg(format!( + "The header of key {} is not existed in the etcd server", + self.property + )) + })?; if header.revision() > self.last_updated_revision { self.last_updated_revision = header.revision(); for ev in resp.take_events() { match ev.event_type() { EventType::Put => { - if let Err(_) = self.read_and_update().await { + if (self.read_and_update().await).is_err() { logging::error!( "Fail to execute process_watch_response() for PUT event" ); } } EventType::Delete => { - if let Err(_) = self.ds.update(None) { + if self.ds.update(None).is_err() { logging::error!( "Fail to execute process_watch_response() for DELETE event" ); diff --git a/sentinel-core/src/datasource/datasource/ds_k8s.rs b/sentinel-core/src/datasource/adapters/ds_k8s.rs similarity index 100% rename from sentinel-core/src/datasource/datasource/ds_k8s.rs rename to sentinel-core/src/datasource/adapters/ds_k8s.rs diff --git a/sentinel-core/src/datasource/datasource/mod.rs b/sentinel-core/src/datasource/adapters/mod.rs similarity index 96% rename from sentinel-core/src/datasource/datasource/mod.rs rename to sentinel-core/src/datasource/adapters/mod.rs index dec578d..e14e6a2 100644 --- a/sentinel-core/src/datasource/datasource/mod.rs +++ b/sentinel-core/src/datasource/adapters/mod.rs @@ -57,7 +57,7 @@ where let mut err = String::new(); for h in &mut self.handlers { let h = Arc::get_mut(h).unwrap(); - let e = h.handle(src.clone()); + let e = h.handle(src); if let Err(e) = e { err.push_str(&format!("{:?}", e)); } @@ -72,11 +72,11 @@ where // return idx if existed, else return None pub fn index_of_handler(&self, h: Arc) -> Option { for (idx, handler) in self.handlers.iter().enumerate() { - if Arc::ptr_eq(&handler, &h) { + if Arc::ptr_eq(handler, &h) { return Some(idx); } } - return None; + None } pub fn add_property_handler(&mut self, h: Arc) { diff --git a/sentinel-core/src/datasource/mod.rs b/sentinel-core/src/datasource/mod.rs index 4b3c4d3..77035e1 100644 --- a/sentinel-core/src/datasource/mod.rs +++ b/sentinel-core/src/datasource/mod.rs @@ -1,8 +1,8 @@ -pub mod datasource; +pub mod adapters; pub mod helpers; pub mod property; -pub use datasource::*; +pub use adapters::*; pub use helpers::*; pub use property::*; diff --git a/sentinel-core/src/datasource/property.rs b/sentinel-core/src/datasource/property.rs index 11e2fc9..e838592 100644 --- a/sentinel-core/src/datasource/property.rs +++ b/sentinel-core/src/datasource/property.rs @@ -26,7 +26,7 @@ pub type PropertyUpdater

= fn(rule: Vec>) -> Result; pub trait PropertyHandler: Send + Sync { // check whether the current src is consistent with last update property - fn is_property_consistent(&mut self, rules: &Vec>) -> bool; + fn is_property_consistent(&mut self, rules: &[Arc

]) -> bool; // handle the current property fn handle(&mut self, src: Option<&String>) -> Result; // update sentinel rules @@ -57,13 +57,13 @@ impl DefaultPropertyHandler

{ impl PropertyHandler

for DefaultPropertyHandler

{ - fn is_property_consistent<'a>(&mut self, rules: &'a Vec>) -> bool { + fn is_property_consistent(&mut self, rules: &[Arc

]) -> bool { if self.last_update_property.is_some() - && &self.last_update_property.as_ref().unwrap() == &rules + && self.last_update_property.as_ref().unwrap() == rules { true } else { - self.last_update_property = Some(rules.clone()); + self.last_update_property = Some(rules.to_vec()); false } } diff --git a/sentinel-core/src/exporter.rs b/sentinel-core/src/exporter.rs index 81d3300..d4035d6 100644 --- a/sentinel-core/src/exporter.rs +++ b/sentinel-core/src/exporter.rs @@ -60,17 +60,10 @@ lazy_static! { ) .unwrap(); static ref GAUGE_METRICS: Vec = { - let mut vec = Vec::new(); - vec.push(CPU_RATIO_GAUGE.clone()); - vec.push(MEMORY_SIZE_GAUGE.clone()); - vec.push(FLOW_THRESHOLD_GAUGE.clone()); - vec + vec![CPU_RATIO_GAUGE.clone(), MEMORY_SIZE_GAUGE.clone(), FLOW_THRESHOLD_GAUGE.clone()] }; static ref COUNTER_METRICS: Vec = { - let mut vec = Vec::new(); - vec.push(STATE_CHANGE_COUNTER.clone()); - vec.push(HANDLED_COUNTER.clone()); - vec + vec![STATE_CHANGE_COUNTER.clone(), HANDLED_COUNTER.clone()] }; static ref INIT_ONCE: Once = Once::new(); } diff --git a/sentinel-core/src/lib.rs b/sentinel-core/src/lib.rs index c749a38..b8d5df1 100644 --- a/sentinel-core/src/lib.rs +++ b/sentinel-core/src/lib.rs @@ -67,14 +67,14 @@ //! use sentinel_core::base; //! use sentinel_core::api::EntryBuilder; //! let entry_builder = EntryBuilder::new(res_name.clone()) -//! .with_traffic_type(base::TrafficType::Inbound); +//! .with_traffic_type(base::TrafficType::Inbound); //! if let Ok(entry) = entry_builder.build() { -//! // The request is allowed to be processed. -//! // after finish the logic, exit the entry. +//! // The request is allowed to be processed. +//! // after finish the logic, exit the entry. //! entry.exit() //! } else { -//! // The request is blocked. -//! // you do not need to call `exit()` on entry now. +//! // The request is blocked. +//! // you do not need to call `exit()` on entry now. //! } //! ``` //! diff --git a/sentinel-core/src/utils/mod.rs b/sentinel-core/src/utils/mod.rs index 290c7c3..f902d84 100644 --- a/sentinel-core/src/utils/mod.rs +++ b/sentinel-core/src/utils/mod.rs @@ -5,8 +5,8 @@ pub mod time; pub use self::time::*; -pub fn is_blank(path: &String) -> bool { - path.trim().len() == 0 +pub fn is_blank(path: &str) -> bool { + path.trim().is_empty() } /// not a general implememtation, diff --git a/sentinel-macros/Cargo.toml b/sentinel-macros/Cargo.toml index 1cb3545..156afd9 100644 --- a/sentinel-macros/Cargo.toml +++ b/sentinel-macros/Cargo.toml @@ -2,7 +2,7 @@ name = "sentinel-macros" version = "0.1.0" authors = ["Forsworns <378974295@qq.com>"] -edition = "2018" +edition = "2021" license = "Apache-2.0" readme = "README.md" documentation = "https://docs.rs/sentinel-core/latest"