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
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
- "spec/01*.lua spec/04*.lua spec/05*.lua spec/06*.lua spec/07*.lua spec/08*.lua"
- "spec/02*.lua"
- "spec/03*.lua"
- "spec/09*.lua"

openresty_version:
- "1.19.9.1"
Expand Down Expand Up @@ -116,7 +117,11 @@ jobs:
- name: Tests
run: |
eval $(luarocks path)
resty -I lib -I spec spec/runner.lua --coverage --verbose -o htest --shuffle-tests ${{ matrix.busted_args }}
if [[ "${{ matrix.busted_args }}" == "spec/09*.lua" ]]; then
resty --shdict 'timer_jump_the_gun 1m' -I lib -I spec spec/runner.lua --coverage --verbose -o htest --shuffle-tests ${{ matrix.busted_args }}
else
resty -I lib -I spec spec/runner.lua --coverage --verbose -o htest --shuffle-tests ${{ matrix.busted_args }}
fi

- name: Show coverage
run: |
Expand Down
9 changes: 8 additions & 1 deletion lib/resty/timerng/job.lua
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,20 @@ function _M.new(wheels, name, callback, delay, once, debug, argc, argv)
},
}

if once then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason we don't do this for recurrent timers?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do this to recurrent timers, they will loop and add +1 step each time they are recreated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they will loop and add +1 step each time they are recreated.

Sorry, I don't understand. The step is assigned by job.new(...) and will never be changed anymore, I think it should not +1 step for each recreation.

Please let me know if I'm wrong, I haven't touched this codebase for a long time.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you are right, I also think it should not +1 step for each recreation, but I found if apply +1 step for recurrent timers, the trigger time maybe +1 step each time:

2024/08/09 12:01:41 [warn] 1218477#1218477: *4 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176101.188, context: ngx.timer
2024/08/09 12:01:42 [warn] 1218477#1218477: *5 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176102.292, context: ngx.timer
2024/08/09 12:01:43 [warn] 1218477#1218477: *6 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176103.394, context: ngx.timer
2024/08/09 12:01:44 [warn] 1218477#1218477: *7 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176104.496, context: ngx.timer
2024/08/09 12:01:45 [warn] 1218477#1218477: *8 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176105.599, context: ngx.timer
2024/08/09 12:01:46 [warn] 1218477#1218477: *10 [lua] 09-jump_the_gun_spec.lua:31: every_func trigger time : 1723176106.701, context: ngx.timer

reproduce

diff --git a/lib/resty/timerng/job.lua b/lib/resty/timerng/job.lua
index 99e3c65..b4c281d 100644
--- a/lib/resty/timerng/job.lua
+++ b/lib/resty/timerng/job.lua
@@ -241,9 +241,9 @@ function _M.new(wheels, name, callback, delay, once, debug, argc, argv)
         },
     }
 
-    if once then
-        self.steps = self.steps + 1
-    end
+    self.steps = self.steps + 1
+    
+    ngx.log(ngx.WARN, "self.steps : ", require("inspect")(self.steps))
 
     if debug then
         job_create_meta(self)
diff --git a/spec/09-jump_the_gun_spec.lua b/spec/09-jump_the_gun_spec.lua
index 545a2f3..325aaf7 100644
--- a/spec/09-jump_the_gun_spec.lua
+++ b/spec/09-jump_the_gun_spec.lua
@@ -28,17 +28,18 @@ end
 
 local function every_func()
     update_time()
+    ngx.log(ngx.WARN, "every_func trigger time : ", require("inspect")(now()))
 end
 
 local rand_intervals = {
-    0.111,
-    0.222,
-    0.333,
-    0.444,
-    0.555,
-    0.666,
-    0.777,
-    0.888,
+    -- 0.111,
+    -- 0.222,
+    -- 0.333,
+    -- 0.444,
+    -- 0.555,
+    -- 0.666,
+    -- 0.777,
+    -- 0.888,
     0.999,
 }
 
@@ -76,7 +77,7 @@ for rand_interval in pairs(rand_intervals) do
         end)
     
         it("test", function ()
-            local delay = 30 * helper.RESOLUTION
+            local delay = 50 * helper.RESOLUTION
             local interval = 10 * helper.RESOLUTION
             update_time()
     
@@ -96,7 +97,7 @@ for rand_interval in pairs(rand_intervals) do
                 )
             end)
     
-            sleep(4)
+            sleep(6)
     
             local dict = ngx.shared["timer_jump_the_gun"]
             if not dict then

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for recurrent timers, if +1 step is added here, such as changing from 10 to 11, then the steps of this recurrent timer will always be 11, and 11 will be obtained each time the pointer is calculated.

self.steps = self.steps + 1
end

if debug then
job_create_meta(self)
end

local create_time = ngx_now()
self.create_time = create_time

if self.name == nil then
self.name = string_format("unix_timestamp=%f;counter=%d:meta=%s",
math_floor(ngx_now() * 1000),
math_floor(create_time * 1000),
NAME_COUNTER,
self.meta.name)

Expand Down
2 changes: 2 additions & 0 deletions lib/resty/timerng/wheel/group.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local math_floor = math.floor

Comment on lines +1 to +2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to remove?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

local utils = require("resty.timerng.utils")
local wheel = require("resty.timerng.wheel")
local array = require("resty.timerng.array")
Expand Down
113 changes: 113 additions & 0 deletions spec/09-jump_the_gun_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@

local timer_module = require("resty.timerng")
local helper = require("helper")

local sleep = ngx.sleep
local update_time = ngx.update_time
local now = ngx.now
local timer_running_count = ngx.timer.running_count
local string_format = string.format


local function callback_func(premature, create_time, delay)
if premature then
return
end

update_time()
local now = now()
local dict = ngx.shared["timer_jump_the_gun"]
if not dict then
error("not found shared dict: timer_jump_the_gun")
return
end

dict:set("not_jump_the_gun", now - delay > create_time)
end


local function every_func()
update_time()
end

local rand_intervals = {
0.111,
0.222,
0.333,
0.444,
0.555,
0.666,
0.777,
0.888,
0.999,
}

for rand_interval in pairs(rand_intervals) do
insulate("timer jump the gun", function ()
local timer = { }

randomize()

lazy_setup(function ()
timer = timer_module.new({
min_threads = 16,
max_threads = 32,
})

assert(timer:start())

end)

lazy_teardown(function ()
timer:freeze()
timer:destroy()

helper.wait_until(function ()
assert.same(1, timer_running_count())
return true
end)

end)

after_each(function ()
assert.has_no.errors(function ()
timer:cancel(helper.TIMER_NAME_ONCE)
end)
end)

it("test", function ()
local delay = 30 * helper.RESOLUTION
local interval = 10 * helper.RESOLUTION
update_time()

assert.has_no.errors(function ()
assert(
timer:every(interval, every_func)
)
end)

sleep(rand_interval)

update_time()
assert.has_no.errors(function ()
local create_time = now()
assert(
timer:named_at("foo", delay, callback_func, create_time, delay)
)
end)

sleep(4)

local dict = ngx.shared["timer_jump_the_gun"]
if not dict then
error("not found shared dict: timer_jump_the_gun")
return
end

local jump_the_gun = dict:get("not_jump_the_gun")
assert.is_not_nil(jump_the_gun)
assert.is_true(jump_the_gun)
end)
end)
end