|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local key = KEYS[1] |
|
|
local requested = tonumber(ARGV[1]) |
|
|
local rate = tonumber(ARGV[2]) |
|
|
local capacity = tonumber(ARGV[3]) |
|
|
|
|
|
|
|
|
local now = redis.call('TIME') |
|
|
local nowInSeconds = tonumber(now[1]) |
|
|
|
|
|
|
|
|
local bucket = redis.call('HMGET', key, 'tokens', 'last_time') |
|
|
local tokens = tonumber(bucket[1]) |
|
|
local last_time = tonumber(bucket[2]) |
|
|
|
|
|
|
|
|
if not tokens or not last_time then |
|
|
tokens = capacity |
|
|
last_time = nowInSeconds |
|
|
else |
|
|
|
|
|
local elapsed = nowInSeconds - last_time |
|
|
local add_tokens = elapsed * rate |
|
|
tokens = math.min(capacity, tokens + add_tokens) |
|
|
last_time = nowInSeconds |
|
|
end |
|
|
|
|
|
|
|
|
local allowed = false |
|
|
if tokens >= requested then |
|
|
tokens = tokens - requested |
|
|
allowed = true |
|
|
end |
|
|
|
|
|
|
|
|
redis.call('HMSET', key, 'tokens', tokens, 'last_time', last_time) |
|
|
|
|
|
|
|
|
return allowed and 1 or 0 |