Skip to content

Commit

Permalink
[feat] Simplified batch update
Browse files Browse the repository at this point in the history
  • Loading branch information
didierofrivia committed Apr 3, 2024
1 parent 2798322 commit e966d0c
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 28 deletions.
8 changes: 0 additions & 8 deletions limitador/src/storage/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ pub fn key_for_counter(counter: &Counter) -> String {
)
}

pub fn keys_for_counters_of_limits(limits: Vec<&Limit>) -> String {
limits
.iter()
.map(|limit| key_for_counters_of_limit(limit))
.collect::<Vec<String>>()
.join(";")
}

pub fn key_for_counters_of_limit(limit: &Limit) -> String {
format!(
"namespace:{{{}}},counters_of_limit:{}",
Expand Down
19 changes: 5 additions & 14 deletions limitador/src/storage/redis/redis_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,27 +281,18 @@ impl AsyncRedisStorage {
let mut con = self.conn_manager.clone();
let span = trace_span!("datastore");

// TODO (didierofrivia): Fix this so we don't iterate twice
let (counters, limits): (Vec<&Counter>, Vec<&Limit>) =
counters_and_deltas.keys().map(|k| (k, k.limit())).unzip();
let (ttls, deltas): (Vec<u64>, Vec<i64>) = counters_and_deltas
.iter()
.map(|(k, v)| (k.seconds(), v))
.unzip();

let redis_script = redis::Script::new(BATCH_UPDATE_COUNTERS);
let mut script_invocation = redis_script.prepare_invoke();

// populate the counter keys in the redis script
for counter_key in counters {
script_invocation.key(key_for_counter(counter_key));
for (counter, delta) in counters_and_deltas {
script_invocation.key(key_for_counter(&counter));
script_invocation.arg(key_for_counters_of_limit(&counter.limit()));
script_invocation.arg(&counter.seconds());
script_invocation.arg(delta);
}

async {
script_invocation
.arg(keys_for_counters_of_limits(limits))
.arg(ttls)
.arg(deltas)
.invoke_async::<_, _>(&mut con)
.await
}
Expand Down
14 changes: 8 additions & 6 deletions limitador/src/storage/redis/scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,22 @@ pub const SCRIPT_UPDATE_COUNTER: &str = "
return c";

// KEYS: List of counter keys
// ARGV[1]: limit keys
// ARGV[2]: TTLs
// ARGV[3]: deltas
// ARGV[j]: Limit keys
// ARGV[j+1]: TTLs
// ARGV[j+2]: Deltas
pub const BATCH_UPDATE_COUNTERS: &str = "
local j = 1
for i, counter_key in ipairs(KEYS) do
local limit_key = ARGV[1][i]
local ttl = tonumber(ARGV[2][i])
local delta = tonumber(ARGV[3][i])
local limit_key = ARGV[j]
local ttl = tonumber(ARGV[j+1])
local delta = tonumber(ARGV[j+2])
local c = redis.call('incrby', counter_key, delta)
if c == delta then
redis.call('expire', counter_key, ttl)
redis.call('sadd', limit_key, counter_key)
end
j = j + 3
end
";

Expand Down

0 comments on commit e966d0c

Please sign in to comment.