@@ -4,16 +4,7 @@ import { ICacheAdapter } from '../@types/adapters'
44
55const logger = createLogger ( 'sliding-window-rate-limiter' )
66
7- export class SlidingWindowRateLimiter implements IRateLimiter {
8- public constructor (
9- private readonly cache : ICacheAdapter ,
10- ) { }
11-
12- public async hit ( key : string , step : number , options : IRateLimiterOptions ) : Promise < boolean > {
13- const timestamp = Date . now ( )
14- const { period, rate } = options
15-
16- const script = `
7+ const SLIDING_WINDOW_RATE_LIMITER_LUA_SCRIPT = `
178 local key = KEYS[1]
189 local timestamp = tonumber(ARGV[1])
1910 local period = tonumber(ARGV[2])
@@ -27,13 +18,16 @@ export class SlidingWindowRateLimiter implements IRateLimiter {
2718 local entries = redis.call('ZRANGE', key, 0, -1)
2819 local hits = 0
2920 for i=1, #entries do
30- local step_str = string.match(entries[i], "^[^:]+:(%d +)")
21+ local step_str = string.match(entries[i], "^[^:]+:([^:] +)")
3122 if step_str then
32- hits = hits + tonumber(step_str)
23+ local entry_step = tonumber(step_str)
24+ if entry_step then
25+ hits = hits + entry_step
26+ end
3327 end
3428 end
3529
36- if hits >= max_rate then
30+ if hits + step > max_rate then
3731 return 1
3832 end
3933
@@ -49,16 +43,25 @@ export class SlidingWindowRateLimiter implements IRateLimiter {
4943 redis.call('PEXPIRE', key, period)
5044
5145 return 0
52- `
46+ `
47+
48+ export class SlidingWindowRateLimiter implements IRateLimiter {
49+ public constructor (
50+ private readonly cache : ICacheAdapter ,
51+ ) { }
52+
53+ public async hit ( key : string , step : number , options : IRateLimiterOptions ) : Promise < boolean > {
54+ const timestamp = Date . now ( )
55+ const { period, rate } = options
5356
54- const result = await this . cache . eval ( script , [ key ] , [
57+ const result = await this . cache . eval ( SLIDING_WINDOW_RATE_LIMITER_LUA_SCRIPT , [ key ] , [
5558 timestamp . toString ( ) ,
5659 period . toString ( ) ,
5760 step . toString ( ) ,
5861 rate . toString ( ) ,
5962 ] )
6063
61- const isRateLimited = result === 1
64+ const isRateLimited = result === 1 || result === '1'
6265
6366 logger ( 'hit on %s bucket: is rate limited? %s' , key , isRateLimited )
6467
0 commit comments