Skip to content

Commit 2abd7a8

Browse files
feat: support specify cost when use incoming function (#1)
1 parent fcce9ca commit 2abd7a8

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

lib/resty/limit/count.lua

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,24 @@ end
4646

4747
-- incoming function using incr with init_ttl
4848
-- need OpenResty version > v0.10.12rc2
49-
local function incoming_new(self, key, commit)
49+
-- parameter "cost" is only supported on the new interface
50+
local function incoming_new(self, key, commit, cost)
51+
cost = cost or 1
52+
assert(cost >= 1)
53+
5054
local dict = self.dict
5155
local limit = self.limit
5256
local window = self.window
5357

5458
local remaining, ok, err
5559

5660
if commit then
57-
remaining, err = dict:incr(key, -1, limit, window)
61+
remaining, err = dict:incr(key, -cost, limit, window)
5862
if not remaining then
5963
return nil, err
6064
end
6165
else
62-
remaining = (dict:get(key) or limit) - 1
66+
remaining = (dict:get(key) or limit) - cost
6367
end
6468

6569
if remaining < 0 then
@@ -74,7 +78,6 @@ local function incoming_old(self, key, commit)
7478
local dict = self.dict
7579
local limit = self.limit
7680
local window = self.window
77-
7881
local remaining, ok, err
7982

8083
if commit then

lib/resty/limit/count.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ This method takes the following arguments:
113113

114114
incoming
115115
--------
116-
**syntax:** `delay, err = obj:incoming(key, commit)`
116+
**syntax:** `delay, err = obj:incoming(key, commit, cost)`
117117

118118
Fires a new request incoming event and calculates the delay needed (if any) for the current request
119119
upon the specified key or whether the user should reject it immediately.
@@ -130,6 +130,8 @@ key so that we can set a rate for individual user.
130130
* `commit` is a boolean value. If set to `true`, the object will actually record the event
131131
in the shm zone backing the current object; otherwise it would just be a "dry run" (which is the default).
132132

133+
* `cost` is the specified number that should be deducted when a new request arrives.
134+
133135
The return values depend on the following cases:
134136

135137
1. If the request does not exceed the `count` value specified in the [new](#new) method, then

t/count.t

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,39 @@ remaining: 1
232232
--- no_error_log
233233
[error]
234234
[lua]
235+
236+
237+
238+
=== TEST 6: specify a cost
239+
--- http_config eval: $::HttpConfig
240+
--- config
241+
location = /t {
242+
content_by_lua_block {
243+
local limit_count = require "resty.limit.count"
244+
ngx.shared.store:flush_all()
245+
local lim = limit_count.new("store", 10, 100)
246+
local uri = ngx.var.uri
247+
for i = 1, 7 do
248+
local delay, err = lim:incoming(uri, true, 2)
249+
if not delay then
250+
ngx.say(err)
251+
else
252+
local remaining = err
253+
ngx.say("remaining: ", remaining)
254+
end
255+
end
256+
}
257+
}
258+
--- request
259+
GET /t
260+
--- response_body
261+
remaining: 8
262+
remaining: 6
263+
remaining: 4
264+
remaining: 2
265+
remaining: 0
266+
rejected
267+
rejected
268+
--- no_error_log
269+
[error]
270+
[lua]

0 commit comments

Comments
 (0)