Skip to content
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

fix: use Node's microtasks policy in node_main.cc #23153

Merged
merged 1 commit into from Apr 21, 2020

Conversation

ckerr
Copy link
Member

@ckerr ckerr commented Apr 17, 2020

Fixes #21515. See that ticket for a looong writeup.

Description of Change

Node uses a kExplicit microtasks policy; previously we were using the V8 default value of kAuto. This PR ensures we use the same policy as Node by extracting it from node::IsolateSettings.

CC @codebytere,@nornagon

Checklist

Release Notes

Notes: Fixed Promise timeout issue when running Electron as Node.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened in the last 24 hours label Apr 17, 2020
@trop
Copy link
Contributor

trop bot commented Apr 17, 2020

@ckerr has manually backported this PR to "9-x-y", please check out #23154

@trop trop bot added the in-flight/9-x-y label Apr 17, 2020
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened in the last 24 hours label Apr 18, 2020
@@ -146,6 +146,10 @@ int NodeMain(int argc, char* argv[]) {
JavascriptEnvironment gin_env(loop);

v8::Isolate* isolate = gin_env.isolate();
// TODO(ckerr) and/or TODO(codebytere) use node::SetIsolateMiscHandlers()
node::IsolateSettings is;
Copy link
Member

Choose a reason for hiding this comment

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

for posterity's sake, can we note that this means v8::MicrotasksPolicy::kExplicit?

Copy link
Member Author

@ckerr ckerr Apr 21, 2020

Choose a reason for hiding this comment

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

My rationale for using node::IsolateSettings wasn't so much "show that we're using kExplicit" as it was "show that we're using whatever Node is using" -- e.g. if they were to change from kExplicit to something else in their code, we would pick up that change automatically.

If we want to make it obvious that the mode is kExplicit, maybe we should just use that directly instead of using IsolateSettings. Would that be your preference?

Copy link
Member

@codebytere codebytere left a comment

Choose a reason for hiding this comment

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

lgtm with a small nit!

@nornagon
Copy link
Member

This seems like a potentially dangerous change since we aren't particularly careful to execute microtasks when we exit a C++ context.

The V8 docs on MicrotasksPolicy say that auto is "microtasks are invoked when the script call depth decrements to zero".

I'm a little hazy as to what the implications are of not having good hygiene around executing microtasks when we ought to be. Could there be issues where e.g. we get an event in C++ (like a tray icon click, for instance), which we then run a JS callback for, but we forget to run microtasks and then the main thread goes back to sleep again without having executed microtasks? Could that result in weird things like promises or timers not executing when they're supposed to?

Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

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

requesting changes to mark unresolved questions

@ckerr
Copy link
Member Author

ckerr commented Apr 21, 2020

Could there be issues where e.g. we get an event in C++ (like a tray icon click, for instance)

This change only affects Electron when running in Node emulation mode -- for the tray icon example, there won't be any tray icon nor clicks in Node emulation mode. 🙂

I don't think there are any callbacks in Node mode that could have side-effects as you're describing -- is there something in particular you have in mind?

Copy link
Member

@nornagon nornagon left a comment

Choose a reason for hiding this comment

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

d'oh, missed that. LGTM then.

That makes me wonder if we also have this problem in non-RUN_AS_NODE mode?

@codebytere
Copy link
Member

@nornagon we don't run into this problem in non-emulation mode bc we already override it. @ckerr has a great writeup linked in PR :)

@nornagon
Copy link
Member

@codebytere ah, I missed the bit in the writeup that mentions that we set this elsewhere during non-RUN_AS_NODE mode.

That's exactly the thing I was concerned about though, which is that we're setting the explicit microtasks mode (at least in the main process), but we possibly aren't consistently invoking microtasks when we need to be.

@codebytere
Copy link
Member

To my knowledge we do via our microtasks runner - we have a specific task observer to flush the queued microtasks which runs at the end of every task and is based off of Blink's EndOfTaskRunner

@codebytere codebytere merged commit 07654c4 into master Apr 21, 2020
@release-clerk
Copy link

release-clerk bot commented Apr 21, 2020

Release Notes Persisted

Fixed Promise timeout issue when running Electron as Node.

@codebytere codebytere deleted the use-nodes-microtask-policy branch April 21, 2020 19:18
@trop
Copy link
Contributor

trop bot commented Apr 28, 2020

@ckerr has manually backported this PR to "7-2-x", please check out #23324

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.

await Promise with Timer behavior regress from previous version
3 participants