Skip to content

Commit fa5e228

Browse files
committed
fix sleep
1 parent 5684054 commit fa5e228

1 file changed

Lines changed: 22 additions & 21 deletions

File tree

lib/resty/timer.lua

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,58 +14,59 @@ local anchor_registry = {}
1414
local gc_registry = setmetatable({},{ __mode = "v" })
1515
local timer_id = 0
1616
local now = ngx.now
17-
local sleep = ngx.sleep
17+
local ngx_sleep = ngx.sleep
1818
local exiting = ngx.worker.exiting
19-
local min = math.min
2019

2120
local KEY_PREFIX = "[lua-resty-timer]"
2221
local LOG_PREFIX = "[resty-timer] "
2322
local CANCEL_GC = "GC"
2423
local CANCEL_SYSTEM = "SYSTEM"
2524
local CANCEL_USER = "USER"
2625

27-
local sleepx do
28-
local SLEEP_BLOCK_SIZE = 5
29-
26+
local sleep do
3027
-- create a 10yr timer only called with `premature` set. The callback will
3128
-- release a global semaphore to wake up sleeping threads
3229
local sema = assert(require("ngx.semaphore").new())
3330
assert(timer_at(10*365*24*60*60, function()
3431
sema:post(math.huge)
32+
33+
-- TODO: remove the below log line, it's an ugly hack around semaphores
34+
-- not being released properly, an Openresty bug.
35+
-- See https://github.com/openresty/lua-resty-core/issues/337
36+
ngx.timer.at(0, function()
37+
ngx.log(ngx.WARN,"please ignore, just generating IO, see https://github.com/openresty/lua-resty-core/issues/337")
38+
end)
3539
end))
3640

3741
--- A `sleep` function that exits early on system exit. The same as `ngx.sleep`
3842
-- except that it will be interrupted when the current worker starts exiting.
3943
-- @param delay same as `ngx.sleep()`; delay in seconds.
4044
-- @return results of `ngx.worker.exiting()`
41-
-- @usage if sleepx(5) then
45+
-- @usage if sleep(5) then
4246
-- -- sleep was interrupted, exit now
4347
-- return nil, "exiting"
4448
-- end
4549
--
4650
-- -- do stuff
47-
function sleepx(delay)
51+
function sleep(delay)
4852
if type(delay) ~= "number" then
4953
error("Bad argument #1, expected number, got " .. type(delay), 2)
5054
end
5155

5256
if delay <= 0 then
53-
sleep(delay)
57+
ngx_sleep(delay)
5458
return exiting()
5559
end
5660

57-
-- this doesn't work
58-
-- see https://github.com/openresty/lua-resty-core/issues/337
59-
-- sema:wait(delay)
60-
-- return exiting()
61-
62-
-- fall-back to sleeping in SLEEP_BLOCK_SIZE sec chunks
63-
local t = now()
64-
local exit_at = t + delay
65-
while exit_at > t and not exiting() do
66-
sleep(min(SLEEP_BLOCK_SIZE, exit_at - t))
67-
t = now()
61+
local _, err = sema:wait(delay)
62+
if err == "timeout" then
63+
return false
6864
end
65+
66+
if err then
67+
ngx.log(ngx.ERR, "waiting for semaphore failed: ", err)
68+
end
69+
6970
return exiting()
7071
end
7172
end
@@ -188,7 +189,7 @@ local function handler(premature, id)
188189
end
189190

190191
-- existing timer recurring, so keep this thread alive and just sleep
191-
premature = sleepx(next_interval)
192+
premature = sleep(next_interval)
192193
end -- while
193194
end
194195

@@ -384,7 +385,7 @@ end
384385
return setmetatable(
385386
{
386387
new = new,
387-
sleepx = sleepx,
388+
sleep = sleep,
388389
CANCEL_GC = CANCEL_GC,
389390
CANCEL_SYSTEM = CANCEL_SYSTEM,
390391
CANCEL_USER = CANCEL_USER,

0 commit comments

Comments
 (0)