-
Notifications
You must be signed in to change notification settings - Fork 30k
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
async_hooks: fast-path for PromiseHooks in JS #32891
Conversation
6e714dd
to
c92c5da
Compare
c92c5da
to
9b75102
Compare
I like the latest commit. I also had an idea that we could use Promise objects as resources without allocating extra wrap objects. I guess, with the current state of this PR it should be ready for initial benchmarking. WDYT? |
Started a micro-benchmarks build: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/561/ |
Got result for
Update. I've added a variation of
I also got results for
I also tried running it with Update. The above benchmarks were run for the previous version of this PoC. They don't highlight current performance. |
@jasnell In regard to the missing trace events we discussed in nodejs/diagnostics#376, do you think it would be reasonable to apply two different wraps depending on if there is a destroy hook? If a destroy hook is present it would apply the full wrap with gc-tracking, and if it's absent it would only apply the simplified wrap. I'm thinking of exposing the wrap class to JS and switching the logic based on the destroy hook presence. Another option would be to have two separate My hope was to be able to separate |
I'm not @jasnell but I can answer this as well. Go ahead with two different wraps depending if there is a destroy hook. It's unlikely we will be ever able to remove the destroy hook, but if we can provide a fast path it would be very handy. I would make sure we emit some debug info when one or the other is turned on ( |
Sounds like a plan. Thanks for the input! 😄 |
11fbcf7
to
282653b
Compare
Landed in 13c5a16 |
This avoids the need to wrap every promise in an AsyncWrap and also makes it easier to skip the machinery to track destroy events when there's no destroy listener. Co-authored-by: Andrey Pechkurov <[email protected]> PR-URL: #32891 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Andrey Pechkurov <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
../src/async_wrap.cc: In function ‘uint16_t node::ToAsyncHooksType(v8::PromiseHookType)’: ../src/async_wrap.cc:313:1: error: control reaches end of non-void function [-Werror=return-type] } Refs: nodejs#32891
../src/async_wrap.cc: In function ‘uint16_t node::ToAsyncHooksType(v8::PromiseHookType)’: ../src/async_wrap.cc:313:1: error: control reaches end of non-void function [-Werror=return-type] } Refs: #32891 PR-URL: #33322 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
This avoids the need to wrap every promise in an AsyncWrap and also makes it easier to skip the machinery to track destroy events when there's no destroy listener. Co-authored-by: Andrey Pechkurov <[email protected]> PR-URL: #32891 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Andrey Pechkurov <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
../src/async_wrap.cc: In function ‘uint16_t node::ToAsyncHooksType(v8::PromiseHookType)’: ../src/async_wrap.cc:313:1: error: control reaches end of non-void function [-Werror=return-type] } Refs: #32891 PR-URL: #33322 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Michaël Zasso <[email protected]>
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) remove obsolete completer variable (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) improve repl autocompletion for require calls (Ruben Bridgewater) #33282 * (SEMVER-MINOR) replace hard coded core module list with actual list (Ruben Bridgewater) #33282 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 test: * (SEMVER-MINOR) refactor test/parallel/test-bootstrap-modules.js (Ruben Bridgewater) #33282 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: TODO
Notable changes: async_hooks: * (SEMVER-MINOR) move PromiseHook handler to JS (Stephen Belanger) #32891 cli: * (SEMVER-MINOR) add `--trace-atomics-wait` flag (Anna Henningsen) #33292 fs: * (SEMVER-MINOR) add .ref() and .unref() methods to watcher classes (rickyes) #33134 http: * (SEMVER-MINOR) expose http.validate-header-name/value (osher) #33119 repl: * (SEMVER-MINOR) deprecate repl._builtinLibs (Ruben Bridgewater) #33294 * (SEMVER-MINOR) deprecate repl.inputStream and repl.outputStream (Ruben Bridgewater) #33294 * (SEMVER-MINOR) show reference errors during preview (Ruben Bridgewater) #33282 * (SEMVER-MINOR) improve repl preview (Ruben Bridgewater) #33282 src: * add support for TLA (Gus Caplan) #30370 PR-URL: #33452
This is an attempt to eliminate the GC-tracking of promises needed to emit destroy events to async_hooks if there is nothing listening to those events. I've replicated the
PromiseHook
handler andPromiseWrap
behaviour in JS to allow a fast-path for handling promise-related events when there is no destroy hook present and therefore no need for expensive gc-tracking. This should significantly improve the performance of async_hooks in promise-heavy applications for the typical/suggested case of context management withAsyncLocalStorage
.With this comes a few important changes to consider:
isChainedPromise
property (Though there are ideas of how this could be restored, if there are objections)