Software /
code /
prosody
Comparison
util/async.lua @ 11962:9a70a543c727
util.async: Add next-tick configuration
Running woken runners in the next iteration of the event loop prevents
unexpected recursion, unexpected tracebacks, and is generally more
predictable.
The pattern is borrowed from util.promise, where we're now doing the same.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 29 Nov 2021 14:14:30 +0000 |
parent | 11961:542a9a503073 |
child | 12310:91af1697ddd8 |
comparison
equal
deleted
inserted
replaced
11961:542a9a503073 | 11962:9a70a543c727 |
---|---|
11 return thread; | 11 return thread; |
12 end | 12 end |
13 | 13 |
14 -- Configurable functions | 14 -- Configurable functions |
15 local schedule_task = nil; -- schedule_task(seconds, callback) | 15 local schedule_task = nil; -- schedule_task(seconds, callback) |
16 local next_tick = function (f) | |
17 f(); | |
18 end | |
16 | 19 |
17 local function runner_from_thread(thread) | 20 local function runner_from_thread(thread) |
18 local level = 0; | 21 local level = 0; |
19 -- Find the 'level' of the top-most function (0 == current level, 1 == caller, ...) | 22 -- Find the 'level' of the top-most function (0 == current level, 1 == caller, ...) |
20 while debug.getinfo(thread, level, "") do level = level + 1; end | 23 while debug.getinfo(thread, level, "") do level = level + 1; end |
60 return runner:run(); | 63 return runner:run(); |
61 elseif state == "ready" then | 64 elseif state == "ready" then |
62 -- If state is 'ready', it is our responsibility to update runner.state from 'waiting'. | 65 -- If state is 'ready', it is our responsibility to update runner.state from 'waiting'. |
63 -- We also have to :run(), because the queue might have further items that will not be | 66 -- We also have to :run(), because the queue might have further items that will not be |
64 -- processed otherwise. FIXME: It's probably best to do this in a nexttick (0 timer). | 67 -- processed otherwise. FIXME: It's probably best to do this in a nexttick (0 timer). |
65 runner.state = "ready"; | 68 next_tick(function () |
66 runner:run(); | 69 runner.state = "ready"; |
70 runner:run(); | |
71 end); | |
67 end | 72 end |
68 return true; | 73 return true; |
69 end | 74 end |
70 | 75 |
71 local function waiter(num) | 76 local function waiter(num) |
284 runner = runner; | 289 runner = runner; |
285 wait = wait_for; -- COMPAT w/trunk pre-0.12 | 290 wait = wait_for; -- COMPAT w/trunk pre-0.12 |
286 wait_for = wait_for; | 291 wait_for = wait_for; |
287 sleep = sleep; | 292 sleep = sleep; |
288 | 293 |
294 set_nexttick = function(new_next_tick) next_tick = new_next_tick; end; | |
289 set_schedule_function = function (new_schedule_function) schedule_task = new_schedule_function; end; | 295 set_schedule_function = function (new_schedule_function) schedule_task = new_schedule_function; end; |
290 }; | 296 }; |