-
Notifications
You must be signed in to change notification settings - Fork 29.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
promises: refactor rejection handling #18207
promises: refactor rejection handling #18207
Conversation
CI: https://ci.nodejs.org/job/node-test-pull-request/12580/ Edit: weird failures in CitGM. Investigating... |
CitGM failures unrelated to this PR but clearly something landed in the last 24 hours that completely destroyed CitGM. |
I'll need a few days to digest this and run through the edge cases we had when we specified the hooks. Pinging (no pressure to participate!) relevant parties @petkaantonov @addaleax @domenic |
Just to distill what's going on in the current loop, here's an outline:
|
let didCall = false; | ||
process.on('unhandledRejection', () => { | ||
assert(!didCall); | ||
didCall = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not sure, but, common.mustCall()
? ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it checks at exit
, this would just keep looping forever until timeout is hit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading the code and testing it - I like the behavior and changes. LGTM.
Remove the unnecessary microTasksTickObject for scheduling microtasks and instead use TickInfo to keep track of whether promise rejections exist that need to be emitted. Consequently allow the microtasks to execute on average fewer times, in more predictable manner than previously. Simplify unhandled & handled rejection tracking to do more in C++ to avoid needing to expose additional info in JS. When new unhandledRejections are emitted within an unhandledRejection handler, allow the event loop to proceed first instead. This means that if the end-user code handles all promise rejections on nextTick, rejections within unhandledRejection now won't spiral into an infinite loop.
0413ebb
to
21a2220
Compare
New CI due to some changed code (If I am not mistaken) https://ci.nodejs.org/job/node-test-pull-request/12619/ |
@BridgeAR It was just rebased to make it possible to run the CitGM. But no harm in extra CI :) |
Landed in d62566e |
Remove the unnecessary microTasksTickObject for scheduling microtasks and instead use TickInfo to keep track of whether promise rejections exist that need to be emitted. Consequently allow the microtasks to execute on average fewer times, in more predictable manner than previously. Simplify unhandled & handled rejection tracking to do more in C++ to avoid needing to expose additional info in JS. When new unhandledRejections are emitted within an unhandledRejection handler, allow the event loop to proceed first instead. This means that if the end-user code handles all promise rejections on nextTick, rejections within unhandledRejection now won't spiral into an infinite loop. PR-URL: #18207 Fixes: #17913 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This does not land cleanly on v9.x, should we backport? |
@MylesBorins v9.x might be missing some preceding commits, I think. I'll have time to look into it at the end of the week or the weekend, swamped with a move right now. Sorry. |
This seem to apply cleanly on v9.x now, I’m removing the label. |
Remove the unnecessary microTasksTickObject for scheduling microtasks and instead use TickInfo to keep track of whether promise rejections exist that need to be emitted. Consequently allow the microtasks to execute on average fewer times, in more predictable manner than previously. Simplify unhandled & handled rejection tracking to do more in C++ to avoid needing to expose additional info in JS. When new unhandledRejections are emitted within an unhandledRejection handler, allow the event loop to proceed first instead. This means that if the end-user code handles all promise rejections on nextTick, rejections within unhandledRejection now won't spiral into an infinite loop. PR-URL: nodejs#18207 Fixes: nodejs#17913 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Remove the unnecessary microTasksTickObject for scheduling microtasks and instead use TickInfo to keep track of whether promise rejections exist that need to be emitted. Consequently allow the microtasks to execute on average fewer times, in more predictable manner than previously. Simplify unhandled & handled rejection tracking to do more in C++ to avoid needing to expose additional info in JS. When new unhandledRejections are emitted within an unhandledRejection handler, allow the event loop to proceed first instead. This means that if the end-user code handles all promise rejections on nextTick, rejections within unhandledRejection now won't spiral into an infinite loop. PR-URL: nodejs#18207 Fixes: nodejs#17913 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
@apapirovski this doesn't land cleanly on |
@codebytere Yeah, probably wouldn't hurt. I have a backlog of things I'm supposed to backport anyway. I'll do them all this weekend. |
Remove the unnecessary microTasksTickObject for scheduling microtasks and instead use TickInfo to keep track of whether promise rejections exist that need to be emitted. Consequently allow the microtasks to execute on average fewer times, in more predictable manner than previously.
Simplify unhandled & handled rejection tracking to do more in C++ to avoid needing to expose additional info in JS. Unite emitting unhandledRejection and rejectionHandled into a single function: emitPromiseRejectionWarnings, which runs after all nextTicks have executed.
When new unhandledRejections are emitted within an unhandledRejection handler, allow the event loop to proceed first instead. This means that if the end-user code handles all promise rejections on nextTick, rejections within unhandledRejection now won't spiral into an infinite loop.
On the whole, this should hopefully make reasoning about nextTick, promises and promise rejections a whole lot simpler.
Fixes: #17913
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
process, promises, src