Skip to content

Commit

Permalink
Merge pull request #169 from yorickvanzweeden/fix-lua-unpack-issue
Browse files Browse the repository at this point in the history
Replace unpack function with loop to avoid 'too many results' error in Redis script
  • Loading branch information
alisaifee committed May 16, 2023
2 parents c039699 + 14f0d6c commit 8ac39b0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
9 changes: 4 additions & 5 deletions limits/resources/redis/lua_scripts/acquire_moving_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ end

local entry = redis.call('lindex', KEYS[1], limit - amount)


if entry and tonumber(entry) >= timestamp - expiry then
return false
end
local entries= {}
for i=1, amount do
entries[i] = timestamp

for i = 1, amount do
redis.call('lpush', KEYS[1], timestamp)
end
redis.call('lpush', KEYS[1], unpack(entries))

redis.call('ltrim', KEYS[1], 0, limit - 1)
redis.call('expire', KEYS[1], expiry)

Expand Down
10 changes: 10 additions & 0 deletions tests/aio/test_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,16 @@ async def test_moving_window_varying_cost(self, uri, args, fixture):
await limiter.clear(five_per_min)
assert await limiter.hit(five_per_min)

@async_moving_window_storage
async def test_moving_window_huge_cost_async(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = MovingWindowRateLimiter(storage)
many_per_min = RateLimitItemPerMinute(1_000_000)
await limiter.hit(many_per_min, cost=999_999)
assert not await limiter.hit(many_per_min, cost=2)
await limiter.clear(many_per_min)
assert await limiter.hit(many_per_min)

@pytest.mark.memcached
async def test_moving_window_memcached(self, memcached):
storage = MemcachedStorage("memcached://localhost:22122")
Expand Down
10 changes: 10 additions & 0 deletions tests/test_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ def test_moving_window_varying_cost(self, uri, args, fixture):
limiter.clear(five_per_min)
assert limiter.hit(five_per_min)

@moving_window_storage
def test_moving_window_huge_cost_sync(self, uri, args, fixture):
storage = storage_from_string(uri, **args)
limiter = MovingWindowRateLimiter(storage)
many_per_min = RateLimitItemPerMinute(1_000_000)
limiter.hit(many_per_min, cost=1_000_000)
assert not limiter.hit(many_per_min, cost=2)
limiter.clear(many_per_min)
assert limiter.hit(many_per_min)

@pytest.mark.memcached
def test_moving_window_memcached(self, memcached):
storage = MemcachedStorage("memcached://localhost:22122")
Expand Down

0 comments on commit 8ac39b0

Please sign in to comment.