proxy-pool/internal/adapters/redisadmission/scripts/fixed_window.lua

40 lines
1.1 KiB
Lua

local key = KEYS[1]
local window_ms = tonumber(ARGV[1])
local global_limit = tonumber(ARGV[2])
local per_key_limit = tonumber(ARGV[3])
local client_field = ARGV[4]
local redis_time = redis.call("TIME")
local now_ms = tonumber(redis_time[1]) * 1000 + math.floor(tonumber(redis_time[2]) / 1000)
local window_id = math.floor(now_ms / window_ms)
local stored_window = redis.call("HGET", key, "window")
if not stored_window or tonumber(stored_window) ~= window_id then
redis.call("DEL", key)
redis.call("HSET", key, "window", window_id)
end
if global_limit > 0 then
local global_used = tonumber(redis.call("HGET", key, "global") or "0")
if global_used >= global_limit then
return "global"
end
end
if per_key_limit > 0 then
local client_used = tonumber(redis.call("HGET", key, client_field) or "0")
if client_used >= per_key_limit then
return "per_key"
end
end
if global_limit > 0 then
redis.call("HINCRBY", key, "global", 1)
end
if per_key_limit > 0 then
redis.call("HINCRBY", key, client_field, 1)
end
redis.call("PEXPIREAT", key, (window_id + 1) * window_ms)
return "ok"