@@ -6,9 +6,9 @@ class Overrated < Overloaded; end
66 attr_accessor :interval
77
88 def initialize ( key , capacity , interval , **opts )
9- super ( key , capacity , **opts )
10-
119 self . interval = interval
10+
11+ super ( key , capacity , @interval_usec , **opts )
1212 end
1313
1414 private def interval = ( interval )
@@ -19,12 +19,28 @@ def initialize(key, capacity, interval, **opts)
1919 LUA_SCRIPT = Berater ::LuaScript ( <<~LUA
2020 local key = KEYS[1]
2121 local ts_key = KEYS[2]
22+ local conf_key = KEYS[3]
2223 local ts = tonumber(ARGV[1])
2324 local capacity = tonumber(ARGV[2])
2425 local interval_usec = tonumber(ARGV[3])
2526 local cost = tonumber(ARGV[4])
2627 local count = 0
2728 local allowed
29+
30+ if conf_key then
31+ local config = redis.call('GET', conf_key)
32+
33+ if config then
34+ -- use dynamic capacity limit
35+ capacity, interval_usec = string.match(config, "(%d+):(%d+)")
36+ capacity = tonumber(capacity)
37+ interval_usec = tonumber(interval_usec)
38+
39+ -- reset ttl for a week
40+ redis.call('EXPIRE', conf_key, 604800)
41+ end
42+ end
43+
2844 local usec_per_drip = interval_usec / capacity
2945
3046 -- timestamp of last update
@@ -61,14 +77,17 @@ def initialize(key, capacity, interval, **opts)
6177 )
6278
6379 def limit ( capacity : nil , cost : 1 , &block )
80+ limit_key = if capacity . nil? && dynamic_limits
81+ config_key
82+ end
6483 capacity ||= @capacity
6584
6685 # timestamp in microseconds
6786 ts = ( Time . now . to_f * 10 **6 ) . to_i
6887
6988 count , allowed = LUA_SCRIPT . eval (
7089 redis ,
71- [ cache_key ( key ) , cache_key ( "#{ key } -ts" ) ] ,
90+ [ cache_key ( key ) , cache_key ( "#{ key } -ts" ) , limit_key ] ,
7291 [ ts , capacity , @interval_usec , cost ]
7392 )
7493
0 commit comments