Skip to content

Commit

Permalink
feat: optimizing and minifying lua script
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother committed Mar 27, 2024
1 parent c8af646 commit 85530b0
Showing 1 changed file with 12 additions and 27 deletions.
39 changes: 12 additions & 27 deletions crates/rate_limit/src/token_bucket.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,24 @@ local refillRate = tonumber(ARGV[3]) -- how many tokens are refilled after each
local now = tonumber(ARGV[4]) -- current timestamp in milliseconds

local results = {}

for i, key in ipairs(keys) do
for i, key in ipairs(KEYS) do
local bucket = redis.call("HMGET", key, "refilledAt", "tokens")
local refilledAt = (bucket[1] == false and tonumber(now) or tonumber(bucket[1]))
local tokens = (bucket[1] == false and tonumber(maxTokens) or tonumber(bucket[2]))

local refilledAt
local tokens

if bucket[1] == false then
refilledAt = now
tokens = maxTokens
else
refilledAt = tonumber(bucket[1])
tokens = tonumber(bucket[2])
end

if now >= refilledAt + interval then
local numRefills = math.floor((now - refilledAt) / interval)
tokens = math.min(maxTokens, tokens + numRefills * refillRate)

refilledAt = refilledAt + numRefills * interval
if tonumber(now) >= refilledAt + interval then
tokens = math.min(tonumber(maxTokens), tokens + math.floor((tonumber(now) - refilledAt) / interval) * tonumber(refillRate))
refilledAt = refilledAt + math.floor((tonumber(now) - refilledAt) / interval) * interval
end

if tokens == 0 then
results[key] = {-1, refilledAt + interval}
if tokens > 0 then
tokens = tokens - 1
redis.call("HSET", key, "refilledAt", refilledAt, "tokens", tokens)
redis.call("PEXPIRE", key, math.ceil(((tonumber(maxTokens) - tokens) / tonumber(refillRate)) * interval))
results[key] = {tokens, refilledAt + interval}
else
local remaining = tokens - 1
local expireAt = math.ceil(((maxTokens - remaining) / refillRate)) * interval

redis.call("HSET", key, "refilledAt", refilledAt, "tokens", remaining)
redis.call("PEXPIRE", key, expireAt)
results[key] = {remaining, refilledAt + interval}
results[key] = {-1, refilledAt + interval}
end
end

-- Redis doesn't support Lua table responses: https://stackoverflow.com/a/24302613
return cjson.encode(results)

0 comments on commit 85530b0

Please sign in to comment.