fix(api): do sliding window rate limiting correctly (hopefully)

This commit is contained in:
alyssa 2024-09-27 16:57:32 +09:00
parent 873643153d
commit 21d647f423
2 changed files with 9 additions and 15 deletions

View file

@ -2,13 +2,11 @@
-- redis.replicate_commands() -- redis.replicate_commands()
local rate_limit_key = KEYS[1] local rate_limit_key = KEYS[1]
local burst = ARGV[1] local rate = ARGV[1]
local rate = ARGV[2] local period = ARGV[2]
local period = ARGV[3] local cost = tonumber(ARGV[3])
-- we're only ever asking for 1 request at a time local burst = rate
-- todo: this is no longer true
local cost = 1 --local cost = tonumber(ARGV[4])
local emission_interval = period / rate local emission_interval = period / rate
local increment = emission_interval * cost local increment = emission_interval * cost

View file

@ -137,24 +137,23 @@ pub async fn do_request_ratelimited(
rlimit.key() rlimit.key()
); );
let burst = 5;
let period = 1; // seconds let period = 1; // seconds
let cost = 1; // todo: update this for group member endpoints
// local rate_limit_key = KEYS[1] // local rate_limit_key = KEYS[1]
// local burst = ARGV[1] // local rate = ARGV[1]
// local rate = ARGV[2] // local period = ARGV[2]
// local period = ARGV[3]
// return {remaining, tostring(retry_after), reset_after} // return {remaining, tostring(retry_after), reset_after}
let resp = redis let resp = redis
.evalsha::<(i32, String, u64), String, Vec<String>, Vec<i32>>( .evalsha::<(i32, String, u64), String, Vec<String>, Vec<i32>>(
LUA_SCRIPT_SHA.to_string(), LUA_SCRIPT_SHA.to_string(),
vec![rl_key.clone()], vec![rl_key.clone()],
vec![burst, rlimit.rate(), period], vec![rlimit.rate(), period, cost],
) )
.await; .await;
match resp { match resp {
Ok((mut remaining, retry_after, reset_after)) => { Ok((remaining, retry_after, reset_after)) => {
// redis's lua doesn't support returning floats // redis's lua doesn't support returning floats
let retry_after: f64 = retry_after let retry_after: f64 = retry_after
.parse() .parse()
@ -175,9 +174,6 @@ pub async fn do_request_ratelimited(
) )
}; };
// the redis script puts burst in remaining for ??? some reason
remaining -= burst - rlimit.rate();
let reset_time = SystemTime::now() let reset_time = SystemTime::now()
.checked_add(Duration::from_secs(reset_after)) .checked_add(Duration::from_secs(reset_after))
.expect("invalid timestamp") .expect("invalid timestamp")