fix ratelimits

This commit is contained in:
spiral 2023-03-18 20:44:50 -04:00
parent 4c6217c48b
commit d120a32904
2 changed files with 20 additions and 8 deletions

View File

@ -1,12 +1,13 @@
-- Copyright (c) 2017 Pavel Pravosud -- this script has side-effects, so it requires replicate commands mode
-- https://github.com/rwz/redis-gcra/blob/master/vendor/perform_gcra_ratelimit.lua -- redis.replicate_commands()
local rate_limit_key = KEYS[1] local rate_limit_key = KEYS[1]
local burst = ARGV[1] local burst = ARGV[1]
local rate = ARGV[2] local rate = ARGV[2]
local period = ARGV[3] local period = ARGV[3]
-- local cost = tonumber(ARGV[4])
local cost = 1 -- we're only ever asking for 1 request at a time
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
@ -44,7 +45,7 @@ if remaining < 0 then
local retry_after = diff * -1 local retry_after = diff * -1
return { return {
0, -- remaining 0, -- remaining
retry_after, tostring(retry_after),
reset_after, reset_after,
} }
end end
@ -54,4 +55,8 @@ if reset_after > 0 then
redis.call("SET", rate_limit_key, new_tat, "EX", math.ceil(reset_after)) redis.call("SET", rate_limit_key, new_tat, "EX", math.ceil(reset_after))
end end
local retry_after = -1 local retry_after = -1
return {remaining, retry_after, reset_after} return {
remaining,
tostring(retry_after),
reset_after
}

View File

@ -88,7 +88,7 @@ pub async fn do_request_ratelimited<B>(
// local burst = ARGV[1] // local burst = ARGV[1]
// local rate = ARGV[2] // local rate = ARGV[2]
// local period = ARGV[3] // local period = ARGV[3]
// return {remaining, retry_after, reset_after} // return {remaining, tostring(retry_after), reset_after}
let resp = redis let resp = redis
.evalsha::<(i32, String, u64), String, Vec<&str>, Vec<i32>>( .evalsha::<(i32, String, u64), String, Vec<&str>, Vec<i32>>(
scriptsha, scriptsha,
@ -99,14 +99,21 @@ pub async fn do_request_ratelimited<B>(
match resp { match resp {
Ok((mut remaining, retry_after, reset_after)) => { Ok((mut remaining, retry_after, reset_after)) => {
// redis's lua doesn't support returning floats
let retry_after: f64 = retry_after
.parse()
.expect("got something that isn't a f64 from redis");
let mut response = if remaining > 0 { let mut response = if remaining > 0 {
next.run(request).await next.run(request).await
} else { } else {
println!("{}", reset_after);
json_err( json_err(
StatusCode::TOO_MANY_REQUESTS, StatusCode::TOO_MANY_REQUESTS,
format!( format!(
// todo: the retry_after is horribly wrong // todo: the retry_after is horribly wrong
r#"{{"message":"429: too many requests","retry_after":{retry_after}}}"# r#"{{"message":"429: too many requests","retry_after":{},"code":0}}"#,
(retry_after * 1_000_f64).ceil() as u64
), ),
) )
}; };