Skip to content

Commit 510e6ec

Browse files
committed
feature: resty.limit.count counts made instead of remaining requests
by keeping track of requests that were made instead of remaining ones it is possible to change the limit on the fly and share one counter between several count limiters with different limits ref: #23 (comment)
1 parent ef08073 commit 510e6ec

File tree

2 files changed

+50
-23
lines changed

2 files changed

+50
-23
lines changed

lib/resty/limit/count.lua

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,53 +41,41 @@ function _M.incoming(self, key, commit)
4141
local limit = self.limit
4242
local window = self.window
4343

44-
local remaining, ok, err
44+
local count, ok, err
4545

4646
if commit then
47-
remaining, err = dict:incr(key, -1, limit)
48-
if not remaining then
47+
count, err = dict:incr(key, 1, 0, window)
48+
49+
if not count then
4950
return nil, err
5051
end
5152

52-
if remaining == limit - 1 then
53+
if count == limit then
5354
ok, err = dict:expire(key, window)
55+
5456
if not ok then
55-
if err == "not found" then
56-
remaining, err = dict:incr(key, -1, limit)
57-
if not remaining then
58-
return nil, err
59-
end
60-
61-
ok, err = dict:expire(key, window)
62-
if not ok then
63-
return nil, err
64-
end
65-
66-
else
67-
return nil, err
68-
end
57+
return nil, err
6958
end
7059
end
7160

7261
else
73-
remaining = (dict:get(key) or limit) - 1
62+
count = (dict:get(key) or 0) + 1
7463
end
7564

76-
if remaining < 0 then
65+
if count > limit then
7766
return nil, "rejected"
7867
end
7968

80-
return 0, remaining
69+
return 0, limit - count
8170
end
8271

83-
8472
-- uncommit remaining and return remaining value
8573
function _M.uncommit(self, key)
8674
assert(key)
8775
local dict = self.dict
8876
local limit = self.limit
8977

90-
local remaining, err = dict:incr(key, 1)
78+
local remaining, err = dict:incr(key, -1)
9179
if not remaining then
9280
if err == "not found" then
9381
remaining = limit

t/count.t

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,42 @@ remaining: 1
232232
--- no_error_log
233233
[error]
234234
[lua]
235+
236+
237+
238+
=== TEST 6: a single key shared by two limits (commit)
239+
--- http_config eval: $::HttpConfig
240+
--- config
241+
location = /t {
242+
content_by_lua_block {
243+
local limit_count = require "resty.limit.count"
244+
local lim1 = limit_count.new("store", 1, 10)
245+
local lim2 = limit_count.new("store", 10, 10)
246+
ngx.shared.store:flush_all()
247+
local key = "foo"
248+
249+
local delay, err = lim1:incoming(key, true)
250+
if not delay then
251+
ngx.say("failed to limit count: ", err)
252+
else
253+
local remaining = err
254+
ngx.say("remaining: ", remaining)
255+
end
256+
257+
local delay, err = lim2:incoming(key, true)
258+
if not delay then
259+
ngx.say("failed to limit count: ", err)
260+
else
261+
local remaining = err
262+
ngx.say("remaining: ", remaining)
263+
end
264+
}
265+
}
266+
--- request
267+
GET /t
268+
--- response_body
269+
remaining: 0
270+
remaining: 8
271+
--- no_error_log
272+
[error]
273+
[lua]

0 commit comments

Comments
 (0)