diff options
Diffstat (limited to 'lualib/redis_scripts/ratelimit_update.lua')
-rw-r--r-- | lualib/redis_scripts/ratelimit_update.lua | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/lualib/redis_scripts/ratelimit_update.lua b/lualib/redis_scripts/ratelimit_update.lua index 682ddd0c6..01ab4e051 100644 --- a/lualib/redis_scripts/ratelimit_update.lua +++ b/lualib/redis_scripts/ratelimit_update.lua @@ -13,68 +13,70 @@ -- p - messages pending (must be decreased by 1) -- dr - current dynamic rate multiplier -- db - current dynamic burst multiplier - -local last = redis.call('HGET', KEYS[1], 'l') +local prefix = KEYS[1] +local last = redis.call('HGET', prefix, 'l') +local now = tonumber(KEYS[2]) local nrcpt = tonumber(KEYS[8]) if not last then -- New bucket (why??) - redis.call('HMSET', KEYS[1], 'l', KEYS[2], 'b', tostring(nrcpt), 'dr', '10000', 'db', '10000', 'p', '0') - redis.call('EXPIRE', KEYS[1], KEYS[7]) + redis.call('HMSET', prefix, 'l', tostring(now), 'b', tostring(nrcpt), 'dr', '10000', 'db', '10000', 'p', '0') + redis.call('EXPIRE', prefix, KEYS[7]) return {1, 1, 1} end local dr, db = 1.0, 1.0 -if tonumber(KEYS[5]) > 1 then +local max_dr = tonumber(KEYS[5]) + +if max_dr > 1 then local rate_mult = tonumber(KEYS[3]) - local rate_limit = tonumber(KEYS[5]) - dr = tonumber(redis.call('HGET', KEYS[1], 'dr')) / 10000 + dr = tonumber(redis.call('HGET', prefix, 'dr')) / 10000 - if rate_mult > 1.0 and dr < rate_limit then + if rate_mult > 1.0 and dr < max_dr then dr = dr * rate_mult if dr > 0.0001 then - redis.call('HSET', KEYS[1], 'dr', tostring(math.floor(dr * 10000))) + redis.call('HSET', prefix, 'dr', tostring(math.floor(dr * 10000))) else - redis.call('HSET', KEYS[1], 'dr', '1') + redis.call('HSET', prefix, 'dr', '1') end - elseif rate_mult < 1.0 and dr > (1.0 / rate_limit) then + elseif rate_mult < 1.0 and dr > (1.0 / max_dr) then dr = dr * rate_mult if dr > 0.0001 then - redis.call('HSET', KEYS[1], 'dr', tostring(math.floor(dr * 10000))) + redis.call('HSET', prefix, 'dr', tostring(math.floor(dr * 10000))) else - redis.call('HSET', KEYS[1], 'dr', '1') + redis.call('HSET', prefix, 'dr', '1') end end end -if tonumber(KEYS[6]) > 1 then +local max_db = tonumber(KEYS[6]) +if max_db > 1 then local rate_mult = tonumber(KEYS[4]) - local rate_limit = tonumber(KEYS[6]) - db = tonumber(redis.call('HGET', KEYS[1], 'db')) / 10000 + db = tonumber(redis.call('HGET', prefix, 'db')) / 10000 - if rate_mult > 1.0 and db < rate_limit then + if rate_mult > 1.0 and db < max_db then db = db * rate_mult if db > 0.0001 then - redis.call('HSET', KEYS[1], 'db', tostring(math.floor(db * 10000))) + redis.call('HSET', prefix, 'db', tostring(math.floor(db * 10000))) else - redis.call('HSET', KEYS[1], 'db', '1') + redis.call('HSET', prefix, 'db', '1') end - elseif rate_mult < 1.0 and db > (1.0 / rate_limit) then + elseif rate_mult < 1.0 and db > (1.0 / max_db) then db = db * rate_mult if db > 0.0001 then - redis.call('HSET', KEYS[1], 'db', tostring(math.floor(db * 10000))) + redis.call('HSET', prefix, 'db', tostring(math.floor(db * 10000))) else - redis.call('HSET', KEYS[1], 'db', '1') + redis.call('HSET', prefix, 'db', '1') end end end -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') if burst < 0 then burst = nrcpt else burst = burst + nrcpt end if pending < nrcpt then pending = 0 else pending = pending - nrcpt end -redis.call('HMSET', KEYS[1], 'b', tostring(burst), 'p', tostring(pending), 'l', KEYS[2]) -redis.call('EXPIRE', KEYS[1], KEYS[7]) +redis.call('HMSET', prefix, 'b', tostring(burst), 'p', tostring(pending), 'l', KEYS[2]) +redis.call('EXPIRE', prefix, KEYS[7]) return {tostring(burst), tostring(dr), tostring(db)}
\ No newline at end of file |