diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-03-25 13:19:35 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-03-25 13:19:35 +0000 |
commit | 5d8aa83eb61e59a2360e7d70e971217f8567d13a (patch) | |
tree | 5c101774de5affa30c7d94ab7ce0afc5f9c0d105 /lualib/redis_scripts/ratelimit_check.lua | |
parent | 0dd7203ee541be133c5fab808305146fc311c4f0 (diff) | |
download | rspamd-5d8aa83eb61e59a2360e7d70e971217f8567d13a.tar.gz rspamd-5d8aa83eb61e59a2360e7d70e971217f8567d13a.zip |
[Minor] Improve style in the scripts
Diffstat (limited to 'lualib/redis_scripts/ratelimit_check.lua')
-rw-r--r-- | lualib/redis_scripts/ratelimit_check.lua | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/lualib/redis_scripts/ratelimit_check.lua b/lualib/redis_scripts/ratelimit_check.lua index 2b2af11bf..e43d34ce1 100644 --- a/lualib/redis_scripts/ratelimit_check.lua +++ b/lualib/redis_scripts/ratelimit_check.lua @@ -16,16 +16,19 @@ local last = redis.call('HGET', KEYS[1], 'l') local now = tonumber(KEYS[2]) local nrcpt = tonumber(KEYS[6]) +local leak_rate = tonumber(KEYS[3]) +local max_burst = tonumber(KEYS[4]) +local prefix = KEYS[1] local dynr, dynb, leaked = 0, 0, 0 if not last then -- New bucket - redis.call('HMSET', KEYS[1], 'l', KEYS[2], 'b', '0', 'dr', '10000', 'db', '10000', 'p', tostring(nrcpt)) - redis.call('EXPIRE', KEYS[1], KEYS[5]) + redis.call('HMSET', prefix, 'l', tostring(now), 'b', '0', 'dr', '10000', 'db', '10000', 'p', tostring(nrcpt)) + redis.call('EXPIRE', prefix, KEYS[5]) return {0, '0', '1', '1', '0'} end - last = tonumber(last) -local burst,pending = unpack(redis.call('HMGET', KEYS[1], 'b', 'p')) + +local burst,pending = unpack(redis.call('HMGET', prefix, 'b', 'p')) burst,pending = tonumber(burst or '0'),tonumber(pending or '0') -- Sanity to avoid races if burst < 0 then burst = 0 end @@ -33,30 +36,30 @@ if pending < 0 then pending = 0 end pending = pending + nrcpt -- this message -- Perform leak if burst + pending > 0 then - if burst > 0 and last < tonumber(KEYS[2]) then - local rate = tonumber(KEYS[3]) - dynr = tonumber(redis.call('HGET', KEYS[1], 'dr')) / 10000.0 + -- If we have any time passed + if burst > 0 and last < now then + dynr = tonumber(redis.call('HGET', prefix, 'dr')) / 10000.0 if dynr == 0 then dynr = 0.0001 end - rate = rate * dynr - leaked = ((now - last) * rate) + leak_rate = leak_rate * dynr + leaked = ((now - last) * leak_rate) if leaked > burst then leaked = burst end burst = burst - leaked - redis.call('HINCRBYFLOAT', KEYS[1], 'b', -(leaked)) - redis.call('HSET', KEYS[1], 'l', KEYS[2]) + redis.call('HINCRBYFLOAT', prefix, 'b', -(leaked)) + redis.call('HSET', prefix, 'l', tostring(now)) end - dynb = tonumber(redis.call('HGET', KEYS[1], 'db')) / 10000.0 + dynb = tonumber(redis.call('HGET', prefix, 'db')) / 10000.0 if dynb == 0 then dynb = 0.0001 end burst = burst + pending - if burst > 0 and (burst + tonumber(KEYS[6])) > tonumber(KEYS[4]) * dynb then + if burst > 0 and (burst + nrcpt) > max_burst * dynb then return {1, tostring(burst - pending), tostring(dynr), tostring(dynb), tostring(leaked)} end -- Increase pending if we allow ratelimit - redis.call('HINCRBY', KEYS[1], 'p', nrcpt) + redis.call('HINCRBY', prefix, 'p', nrcpt) else burst = 0 - redis.call('HMSET', KEYS[1], 'b', '0', 'p', tostring(nrcpt)) + redis.call('HMSET', prefix, 'b', '0', 'p', tostring(nrcpt)) end return {0, tostring(burst), tostring(dynr), tostring(dynb), tostring(leaked)}
\ No newline at end of file |