diff --git a/Cargo.lock b/Cargo.lock index 83d407a..85a692f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,7 +172,7 @@ dependencies = [ [[package]] name = "gcra" -version = "0.5.0" +version = "0.6.0" dependencies = [ "chrono", "dashmap", diff --git a/Cargo.toml b/Cargo.toml index a9a99fe..4a62026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gcra" -version = "0.5.0" +version = "0.6.0" edition = "2021" authors = ["Sam Shih "] license = "MIT" diff --git a/examples/rate_limiter.rs b/examples/rate_limiter.rs index 5131aa5..63fe612 100644 --- a/examples/rate_limiter.rs +++ b/examples/rate_limiter.rs @@ -8,10 +8,10 @@ async fn main() -> Result<(), GcraError> { let rate_limit = RateLimit::per_sec(2); let rl = RateLimiter::with_shards(CACHE_CAPACITY, WORKER_SHARD_COUNT); - rl.check("key", rate_limit.clone(), 1).await?; - rl.check("key", rate_limit.clone(), 1).await?; + rl.check("key", &rate_limit, 1).await?; + rl.check("key", &rate_limit, 1).await?; - match rl.check("key", rate_limit.clone(), 1).await { + match rl.check("key", &rate_limit, 1).await { Err(GcraError::DeniedUntil { next_allowed_at }) => { print!("Denied: Request next at {:?}", next_allowed_at); Ok(()) diff --git a/src/lib.rs b/src/lib.rs index 7db17eb..cd64abb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,10 +36,10 @@ //! let rate_limit = RateLimit::per_sec(2); //! let rl = RateLimiter::new(4); //! -//! rl.check("key", rate_limit.clone(), 1).await?; -//! rl.check("key", rate_limit.clone(), 1).await?; +//! rl.check("key", &rate_limit, 1).await?; +//! rl.check("key", &rate_limit, 1).await?; //! -//! match rl.check("key", rate_limit.clone(), 1).await { +//! match rl.check("key", &rate_limit, 1).await { //! Err(GcraError::DeniedUntil { next_allowed_at }) => { //! print!("Denied: Request next at {:?}", next_allowed_at); //! Ok(()) diff --git a/src/rate_limiter/rate_limiter.rs b/src/rate_limiter/rate_limiter.rs index 854ce2f..ba566df 100644 --- a/src/rate_limiter/rate_limiter.rs +++ b/src/rate_limiter/rate_limiter.rs @@ -82,7 +82,7 @@ where pub async fn check( &self, key: Key, - rate_limit: RateLimit, + rate_limit: &RateLimit, cost: u32, ) -> Result { self.check_at(key, rate_limit, cost, self.clock.now()).await @@ -96,16 +96,16 @@ where pub async fn check_at( &self, key: Key, - rate_limit: RateLimit, + rate_limit: &RateLimit, cost: u32, arrived_at: Instant, ) -> Result { let request_key = RateLimitRequest { key }; let mut entry = self.map.entry(request_key.clone()).or_default(); - match entry.check_and_modify_at(&rate_limit, arrived_at, cost) { + match entry.check_and_modify_at(rate_limit, arrived_at, cost) { Ok(_) => { - entry.update_expiration(&rate_limit); + entry.update_expiration(rate_limit); // Guaranteed to be set from update_expiration let expires_at = entry.expires_at.unwrap(); Ok(expires_at) @@ -147,12 +147,12 @@ mod tests { for _ in 0..rate_limit.resource_limit { assert!( - rl.check("key", rate_limit.clone(), 1).await.is_ok(), + rl.check("key", &rate_limit, 1).await.is_ok(), "Shouldn't be rate limited yet" ); } - match rl.check("key", rate_limit, 1).await { + match rl.check("key", &rate_limit, 1).await { Ok(_) => panic!("We should be rate limited"), Err(GcraError::DeniedUntil { next_allowed_at }) => { assert!(next_allowed_at > Instant::now()) @@ -166,7 +166,7 @@ mod tests { let rate_limit = RateLimit::new(3, Duration::from_secs(3)); let rl = RateLimiter::with_shards(4, 2); - match rl.check("key", rate_limit.clone(), 9).await { + match rl.check("key", &rate_limit, 9).await { Ok(_) => panic!("We should be rate limited"), Err(GcraError::DeniedIndefinitely { cost, @@ -185,49 +185,29 @@ mod tests { let rl = RateLimiter::with_shards(4, 2); let now = Instant::now(); - assert!(rl.check_at("key", rate_limit.clone(), 1, now).await.is_ok()); + assert!(rl.check_at("key", &rate_limit, 1, now).await.is_ok()); assert!( - rl.check_at( - "key", - rate_limit.clone(), - 1, - now + Duration::from_millis(250) - ) - .await - .is_ok(), + rl.check_at("key", &rate_limit, 1, now + Duration::from_millis(250)) + .await + .is_ok(), "delay the 2nd check" ); assert!( - rl.check_at( - "key", - rate_limit.clone(), - 1, - now + Duration::from_millis(251) - ) - .await - .is_err(), + rl.check_at("key", &rate_limit, 1, now + Duration::from_millis(251)) + .await + .is_err(), "check we are denied start" ); assert!( - rl.check_at( - "key", - rate_limit.clone(), - 1, - now + Duration::from_millis(499) - ) - .await - .is_err(), + rl.check_at("key", &rate_limit, 1, now + Duration::from_millis(499)) + .await + .is_err(), "check we are denied end" ); assert!( - rl.check_at( - "key", - rate_limit.clone(), - 1, - now + Duration::from_millis(501) - ) - .await - .is_ok(), + rl.check_at("key", &rate_limit, 1, now + Duration::from_millis(501)) + .await + .is_ok(), "1st use should be released" ) } @@ -241,7 +221,7 @@ mod tests { for index in 0..rate_limit.resource_limit { assert!( - rl.check(index, rate_limit.clone(), 1).await.is_ok(), + rl.check(index, &rate_limit, 1).await.is_ok(), "Shouldn't be rate limited yet" ); }