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
4 changes: 3 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,14 @@ Specifies the maximal step size (i.e., sleep interval, in seconds) allowed. See

lock
----
`syntax: elapsed, err = obj:lock(key)`
`syntax: elapsed, err = obj:lock(key, exptime)`

Tries to lock a key across all the Nginx worker processes in the current Nginx server instance. Different keys are different locks.

The length of the key string must not be larger than 65535 bytes.

The optional `exptime` argument allows to set an expiration time (in seconds) for the key.

Returns the waiting time (in seconds) if the lock is successfully acquired. Otherwise returns `nil` and a string describing the error.

The waiting time is not from the wallclock, but rather is from simply adding up all the waiting "steps". A nonzero `elapsed` return value indicates that someone else has just hold this lock. But a zero return value cannot gurantee that no one else has just acquired and released the lock.
Expand Down
7 changes: 5 additions & 2 deletions lib/resty/lock.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function _M.new(_, dict_name, opts)
end


function _M.lock(self, key)
function _M.lock(self, key, exptime)
if not key then
return nil, "nil key"
end
Expand All @@ -127,7 +127,7 @@ function _M.lock(self, key)
if cdata.key_id > 0 then
return nil, "locked"
end
local exptime = self.exptime
local exptime = exptime or self.exptime
local ok, err = dict:add(key, true, exptime)
if ok then
cdata.key_id = ref_obj(key)
Expand All @@ -143,6 +143,9 @@ function _M.lock(self, key)
local step = self.step
local ratio = self.ratio
local timeout = self.timeout
if timeout and timeout > exptime then
timeout = exptime
end
local max_step = self.max_step
local elapsed = 0
while timeout > 0 do
Expand Down
34 changes: 34 additions & 0 deletions t/sanity.t
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,37 @@ lock 2: unlock: nil, unlocked
--- no_error_log
[error]



=== TEST 14: lock expired by itself when set per key
--- http_config eval: $::HttpConfig
--- config
location = /t {
content_by_lua '
local resty_lock = require "resty.lock"
local key = "blah"
local t, err = ngx.thread.spawn(function ()
local lock = resty_lock:new("cache_locks")
local elapsed, err = lock:lock(key, 0.1)
ngx.say("sub thread: lock: ", elapsed, " ", err)
ngx.sleep(0.1)
-- ngx.say("sub thread: unlock: ", lock:unlock(key))
end)

local lock = resty_lock:new("cache_locks", { max_step = 0.05 })
local elapsed, err = lock:lock(key)
ngx.say("main thread: lock: ", elapsed, " ", err)
ngx.say("main thread: unlock: ", lock:unlock())
';
}
--- request
GET /t
--- response_body_like chop
^sub thread: lock: 0 nil
main thread: lock: 0.11[2-4]\d* nil
main thread: unlock: 1
$
--- no_error_log
[error]