Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ This library provides several Lua modules to help OpenResty/ngx_lua users to con
limit
the traffic, either request rate or request concurrency (or both).

* [resty.limit.req](lib/resty/limit/req.md) provides request rate limiting and adjustment based on the "leaky bucket" method.
* [resty.limit.req](lib/resty/limit/req.md) provides request rate limiting and adjustment based on the "leaky bucket" + "sliding window" method.
* [resty.limit.count](lib/resty/limit/count.md) provides rate limiting based on a "fixed window" implementation since OpenResty 1.13.6.1+.
* [resty.limit.conn](lib/resty/limit/conn.md) provides request concurrency level limiting and adjustment based on extra delays.
* [resty.limit.traffic](lib/resty/limit/traffic.md) provides an aggregator to combine multiple instances of the [resty.limit.req](lib/resty/limit/req.md), [resty.limit.count](lib/resty/limit/count.md), or [resty.limit.conn](lib/resty/limit/conn.md) classes (or all).
Expand Down
41 changes: 27 additions & 14 deletions lib/resty/limit/conn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ local floor = math.floor
local ngx_shared = ngx.shared
local assert = assert


---@class resty.limit.conn
---@field dict ngx.shared.DICT
---@field max number
---@field burst number
---@field unit_delay number
---@field committed boolean?
local _M = {
_VERSION = '0.09'
}
Expand All @@ -22,7 +27,11 @@ local mt = {
__index = _M
}


---@param dict_name string
---@param max integer
---@param burst integer
---@param default_conn_delay number
---@return table?, string?
function _M.new(dict_name, max, burst, default_conn_delay)
local dict = ngx_shared[dict_name]
if not dict then
Expand All @@ -33,21 +42,24 @@ function _M.new(dict_name, max, burst, default_conn_delay)

local self = {
dict = dict,
max = max + 0, -- just to ensure the param is good
max = max + 0, -- just to ensure the param is good
burst = burst,
unit_delay = default_conn_delay,
}

return setmetatable(self, mt)
return setmetatable(self, mt), nil
end


---@param key string|number
---@param commit boolean
---@return number?, number|((ngx.shared.DICT.error)?)
function _M.incoming(self, key, commit)
local dict = self.dict
local max = self.max

self.committed = false

---@type integer?, (ngx.shared.DICT.error)?
local conn, err
if commit then
conn, err = dict:incr(key, 1, 0)
Expand All @@ -63,7 +75,6 @@ function _M.incoming(self, key, commit)
return nil, "rejected"
end
self.committed = true

else
conn = (dict:get(key) or 0) + 1
if conn > max + self.burst then
Expand All @@ -80,12 +91,14 @@ function _M.incoming(self, key, commit)
return 0, conn
end


---@return boolean?
function _M.is_committed(self)
return self.committed
end


---@param key string|number
---@param req_latency number?
---@return integer?, (ngx.shared.DICT.error)?
function _M.leaving(self, key, req_latency)
assert(key)
local dict = self.dict
Expand All @@ -103,23 +116,23 @@ function _M.leaving(self, key, req_latency)
return conn
end


---@param key string|number
---@return integer?, (ngx.shared.DICT.error)?, boolean
function _M.uncommit(self, key)
assert(key)
local dict = self.dict

return dict:incr(key, -1)
end


function _M.set_conn(self, conn)
self.max = conn
---@param max_conn integer
function _M.set_conn(self, max_conn)
self.max = max_conn
end


---@param burst integer
function _M.set_burst(self, burst)
self.burst = burst
end


return _M
33 changes: 26 additions & 7 deletions lib/resty/limit/count.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ local setmetatable = setmetatable
local assert = assert


---@class resty.limit.count
---@field dict ngx.shared.DICT
---@field limit integer
---@field window integer
local _M = {
_VERSION = '0.09'
_VERSION = '0.09'
}


local mt = {
__index = _M
}

---@type boolean
local incr_support_init_ttl
local ngx_config = ngx.config
local ngx_lua_v = ngx.config.ngx_lua_version
Expand All @@ -25,8 +30,12 @@ else
end


-- the "limit" argument controls number of request allowed in a time window.
-- time "window" argument controls the time window in seconds.
--- the "limit" argument controls number of request allowed in a time window.
--- time "window" argument controls the time window in seconds.
---@param dict_name string
---@param limit integer
---@param window integer
---@return resty.limit.count?, string?
function _M.new(dict_name, limit, window)
local dict = ngx_shared[dict_name]
if not dict then
Expand All @@ -41,16 +50,21 @@ function _M.new(dict_name, limit, window)
window = window,
}

return setmetatable(self, mt)
return setmetatable(self, mt), nil
end

-- incoming function using incr with init_ttl
-- need OpenResty version > v0.10.12rc2
---@param self resty.limit.count
---@param key string|number
---@param commit boolean
---@return integer?, number|((ngx.shared.DICT.error)?)
local function incoming_new(self, key, commit)
local dict = self.dict
local limit = self.limit
local window = self.window

---@type integer?, (ngx.shared.DICT.error)?
local remaining, err

if commit then
Expand All @@ -70,11 +84,16 @@ local function incoming_new(self, key, commit)
end

-- incoming function using incr and expire
---@param self resty.limit.count
---@param key string|number
---@param commit boolean
---@return integer?, number|((ngx.shared.DICT.error)?)
local function incoming_old(self, key, commit)
local dict = self.dict
local limit = self.limit
local window = self.window

---@type integer?, boolean?, (ngx.shared.DICT.error)?
local remaining, ok, err

if commit then
Expand All @@ -96,13 +115,11 @@ local function incoming_old(self, key, commit)
if not ok then
return nil, err
end

else
return nil, err
end
end
end

else
remaining = (dict:get(key) or limit) - 1
end
Expand All @@ -117,6 +134,9 @@ end
_M.incoming = incr_support_init_ttl and incoming_new or incoming_old

-- uncommit remaining and return remaining value
---@param self resty.limit.count
---@param key string|number
---@return integer?, (ngx.shared.DICT.error)?
function _M.uncommit(self, key)
assert(key)
local dict = self.dict
Expand All @@ -134,5 +154,4 @@ function _M.uncommit(self, key)
return remaining
end


return _M
Loading