Skip to content

win,unix: change execution order of timers#3927

Merged
trevnorris merged 1 commit intolibuv:v1.xfrom
trevnorris:move-timer-exec
Mar 20, 2023
Merged

win,unix: change execution order of timers#3927
trevnorris merged 1 commit intolibuv:v1.xfrom
trevnorris:move-timer-exec

Conversation

@trevnorris
Copy link
Copy Markdown
Member

The maximum number of times timers should run when uv_run() is called with UV_RUN_ONCE and UV_RUN_NOWAIT is 1. Do that by conditionally calling timers before entering the while loop when called with UV_RUN_DEFAULT.

The reason to always run timers at the end of the while loop, instead of at the beginning, is to help enforce the conceptual event loop model. Which starts when entering the event provider (e.g. calling poll).

Other than only allowing timers to be processed once per uv_run() execution, the only other noticeable change this will show is if all the following are true:

  • uv_run() is called with UV_RUN_NOWAIT or UV_RUN_ONCE.
  • An event is waiting to be received when poll is called.
  • Execution time between the call to uv_timer_start() and entering the while loop is longer than the timeout.

If all these are true, then timers that would have executed before entering the event provider will now be executed afterward.

@bnoordhuis I've also tested this in node.js and all tests passed. Want your feedback if this approach is appropriate, and if you think it's v1.x compatible.

@vtjnash
Copy link
Copy Markdown
Member

vtjnash commented Mar 16, 2023

This sounds sane to me, and easy to update in v2 to drop the first check. However, it means this diagram will need to be updated:
loop_iteration.png
(included on this page https://github.com/libuv/libuv/blob/v1.x/docs/src/design.rst)

@mmomtchev
Copy link
Copy Markdown
Contributor

This is simply running the timers after the polling - which was @vtjnash original proposal

I don't think that running the timers before entering the event loop will have any effect - there are usually no timers waiting when the event loop is started

I did test this back when the issue was initially discussed and the conclusion was that it didn't break anything in Node.js

Still, it appeared a risky change despite its elegance - but it is probably the best solution

Copy link
Copy Markdown
Member

@santigimeno santigimeno left a comment

Choose a reason for hiding this comment

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

LGTM. Not 100% it won't break anyone but if the Node.js test suite is not complaining we could give it a chance (we can always revert, right?)

@trevnorris
Copy link
Copy Markdown
Member Author

@mmomtchev I must have missed that original proposal by @vtjnash.

I agree that it shouldn't make a difference, and Node.js has even stated that users shouldn't depend on the execution order of each event loop phase, but it's been outlined in documents such as https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick and it's what is expected at this point.

The following shows a crazy example, but one that would change execution order if we removed the first call to timers:

require('fs').open('/tmp/tmp.file', 'w', () => console.log('opened'));

setTimeout(() => console.log('setTimeout'), 10);

process.nextTick(() => {
  console.log('nextTick');
  const t = Date.now();
  while (Date.now() - t < 10);
});

Call order now is nextTick, setTimeout, opened. Whereas it would be nextTick, opened, setTimeout removing the initial timer processing call (if the file system is fast enough). Basically, it prioritizes running timers before processing events. Should it matter? No. Will it matter? Possibly. At least enough that I think it's necessary to always run timers before entering the loop in the case of UV_RUN_DEFAULT.

@trevnorris
Copy link
Copy Markdown
Member Author

@vtjnash Is there a diagram file I can update to regenerate the loop_iteration.png file?

The maximum number of times timers should run when uv_run() is called
with UV_RUN_ONCE and UV_RUN_NOWAIT is 1. Do that by conditionally
calling timers before entering the while loop when called with
UV_RUN_DEFAULT.

The reason to always run timers at the end of the while loop, instead of
at the beginning, is to help enforce the conceptual event loop model.
Which starts when entering the event provider (e.g. calling poll).

Other than only allowing timers to be processed once per uv_run()
execution, the only other noticeable change this will show is if all the
following are true:
* uv_run() is called with UV_RUN_NOWAIT or UV_RUN_ONCE.
* An event is waiting to be received when poll is called.
* Execution time between the call to uv_timer_start() and entering the
  while loop is longer than the timeout.

If all these are true, then timers that would have executed before
entering the event provider will now be executed afterward.

Fixes: libuv#3686
Co-authored-by: Momtchil Momtchev <momtchil@momtchev.com>
@trevnorris
Copy link
Copy Markdown
Member Author

@vtjnash I tried my best to regenerate the graphic for the event loop. Let me know if you want any changes.

@trevnorris trevnorris merged commit 6600954 into libuv:v1.x Mar 20, 2023
@trevnorris trevnorris deleted the move-timer-exec branch March 20, 2023 16:05
santigimeno added a commit to santigimeno/node that referenced this pull request May 20, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

- Fixes: nodejs#43931
- Fixes: nodejs#42496
santigimeno added a commit to santigimeno/node that referenced this pull request May 24, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: nodejs#43931
Fixes: nodejs#42496
Fixes: nodejs#47715
Fixes: nodejs#47259
Fixes: nodejs#47241
nodejs-github-bot pushed a commit to nodejs/node that referenced this pull request May 24, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: #43931
Fixes: #42496
Fixes: #47715
Fixes: #47259
Fixes: #47241
PR-URL: #48078
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
trevnorris added a commit to trevnorris/libuv that referenced this pull request May 24, 2023
There should be no need to run timers prior to entering the event loop.
Instead allow them to run normally at the end after the poll phase is
complete.

Ref: libuv#3927
Ref: libuv#4017
trevnorris added a commit to trevnorris/libuv that referenced this pull request May 25, 2023
There should be no need to run timers prior to entering the event loop.
Instead allow them to run normally at the end after the poll phase is
complete.

Ref: libuv#3927
Ref: libuv#4017
trevnorris added a commit to trevnorris/libuv that referenced this pull request May 25, 2023
There should be no need to run timers prior to entering the event loop.
Instead allow them to run normally at the end after the poll phase is
complete.

Ref: libuv#3927
Ref: libuv#4017
targos pushed a commit to nodejs/node that referenced this pull request Jun 4, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: #43931
Fixes: #42496
Fixes: #47715
Fixes: #47259
Fixes: #47241
PR-URL: #48078
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Ceres6 pushed a commit to Ceres6/node that referenced this pull request Aug 14, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: nodejs#43931
Fixes: nodejs#42496
Fixes: nodejs#47715
Fixes: nodejs#47259
Fixes: nodejs#47241
PR-URL: nodejs#48078
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Ceres6 pushed a commit to Ceres6/node that referenced this pull request Aug 14, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: nodejs#43931
Fixes: nodejs#42496
Fixes: nodejs#47715
Fixes: nodejs#47259
Fixes: nodejs#47241
PR-URL: nodejs#48078
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
arsnyder16 pushed a commit to arsnyder16/node that referenced this pull request Sep 10, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: nodejs#43931
Fixes: nodejs#42496
Fixes: nodejs#47715
Fixes: nodejs#47259
Fixes: nodejs#47241
PR-URL: nodejs#48078
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
ruyadorno pushed a commit to nodejs/node that referenced this pull request Sep 11, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: #43931
Fixes: #42496
Fixes: #47715
Fixes: #47259
Fixes: #47241
PR-URL: #48078
Backport-PR-URL: #49591
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
ruyadorno pushed a commit to nodejs/node that referenced this pull request Sep 13, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: #43931
Fixes: #42496
Fixes: #47715
Fixes: #47259
Fixes: #47241
PR-URL: #48078
Backport-PR-URL: #49591
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
ruyadorno pushed a commit to nodejs/node that referenced this pull request Sep 17, 2023
- linux: introduce io_uring support libuv/libuv#3952
- src: add new metrics APIs libuv/libuv#3749
- unix,win: give thread pool threads an 8 MB stack libuv/libuv#3787
- win,unix: change execution order of timers libuv/libuv#3927

Fixes: #43931
Fixes: #42496
Fixes: #47715
Fixes: #47259
Fixes: #47241
PR-URL: #48078
Backport-PR-URL: #49591
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants