Skip to content

Commit

Permalink
Merge pull request #399 from Kuadrant/qualified_deletes
Browse files Browse the repository at this point in the history
Delete counters of qualified limits
  • Loading branch information
alexsnaps authored Jan 30, 2025
2 parents 9b9601f + 0acb833 commit 066b218
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
28 changes: 28 additions & 0 deletions limitador/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ fn classify_limits_by_namespace(
mod test {
use crate::limit::{Context, Expression, Limit};
use crate::RateLimiter;
use std::collections::HashMap;

#[test]
fn properly_updates_existing_limits() {
Expand Down Expand Up @@ -729,4 +730,31 @@ mod test {
.unwrap();
assert_eq!(r.counters.first().unwrap().max_value(), 50);
}

#[test]
fn deletes_qualified_counters() {
let rl = RateLimiter::new(100);
let namespace = "foo";

let l = Limit::new(
namespace,
42,
100,
vec![],
vec![Expression::parse("x").unwrap()],
);
let ctx = Context::from(HashMap::from([("x".to_string(), "a".to_string())]));
rl.add_limit(l.clone());
let r = rl
.check_rate_limited_and_update(&namespace.into(), &ctx, 1, true)
.unwrap();
assert_eq!(r.counters.first().unwrap().remaining(), Some(41));
rl.delete_limit(&l).unwrap();

rl.add_limit(l.clone());
let r = rl
.check_rate_limited_and_update(&namespace.into(), &ctx, 1, true)
.unwrap();
assert_eq!(r.counters.first().unwrap().remaining(), Some(41));
}
}
23 changes: 20 additions & 3 deletions limitador/src/storage/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::counter::Counter;
use crate::limit::{Context, Limit, Namespace};
use crate::storage::atomic_expiring_value::AtomicExpiringValue;
use crate::storage::{Authorization, CounterStorage, StorageErr};
use moka::sync::Cache;
use moka::sync::{Cache, CacheBuilder};
use moka::PredicateError;
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::ops::Deref;
Expand Down Expand Up @@ -198,7 +199,9 @@ impl InMemoryStorage {
pub fn new(cache_size: u64) -> Self {
Self {
simple_limits: RwLock::new(BTreeMap::new()),
qualified_counters: Cache::new(cache_size),
qualified_counters: CacheBuilder::new(cache_size)
.support_invalidation_closures()
.build(),
}
}

Expand Down Expand Up @@ -230,7 +233,21 @@ impl InMemoryStorage {
}

fn delete_counters_of_limit(&self, limit: &Limit) {
self.simple_limits.write().unwrap().remove(limit);
if limit.variables().is_empty() {
self.simple_limits.write().unwrap().remove(limit);
} else {
let l = limit.clone();
if let Err(PredicateError::InvalidationClosuresDisabled) = self
.qualified_counters
.invalidate_entries_if(move |c, _| c.limit() == &l)
{
for (c, _) in self.qualified_counters.iter() {
if c.limit() == limit {
self.qualified_counters.invalidate(&c);
}
}
}
}
}

fn counter_is_within_limits(counter: &Counter, current_val: Option<&u64>, delta: u64) -> bool {
Expand Down

0 comments on commit 066b218

Please sign in to comment.