local cache_key = KEYS[1] local amount = tonumber(ARGV[1]) local current_time = tonumber(ARGV[2]) local outflow = tonumber(ARGV[3]) local maximum = tonumber(ARGV[4]) local leak = function(count, last_touched, current_time, outflow) if count > 0 then local timespan = current_time - last_touched local loss = outflow * timespan if loss > 0 then count = count - loss end end return count, last_touched end local count, last_touched = unpack(redis.call('HMGET', cache_key, 'count', 'timestamp')) count = tonumber(count or 0) last_touched = tonumber(last_touched or current_time) count, last_touched = leak(count, last_touched, current_time, outflow) if count < 0 then count = 0 end count = count + amount if count < 0 then count = 0 end if count > maximum then count = maximum end redis.call('HMSET', cache_key, 'count', count, 'timestamp', current_time) redis.call('EXPIRE', cache_key, 600) return { tostring(count), tostring(current_time) }