-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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: add sync enterWith to async storage #31945
Conversation
27520d1
to
40ea852
Compare
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 am ambivalent on this as it can introduce hard-to-understand behaviors. So if we land this, we need to be extra-clear regareding doc.
@vdeturckheim I disagree that the behaviour of this is any more "hard to understand" than the run(store, callback, ...args) {
this._enter(store);
process.nextTick(callback, ...args);
this._exit();
} Are functionally identical to this: run(store, callback, ...args) {
process.nextTick(() => {
this._enter(store);
callback(...args);
});
} In a related note, I pointed out in my AsyncLocal PR that "exit" events are actually redundant, and this is why. An enter/exit is actually just a single state transition. There's never actually a case where the context would need to exit without explicit user intervention when they specifically want to escape the context for something such as preventing a connection pool from associating with the wrong thing. The sync version could just as easily simply be an With the |
@Qard I remeber you pointed out that such method were actually problematic in domain when it was suggested we exposed |
It's not enter that is the problem, it's exit. Misuse of an exit method can result in context loss. In the case of domains, they also had the problem that domains are bound globally so one could do |
I get your point regarding globally exposed objects or not, I still think there will be shared instances of The domain post-mortem highlights an issue only based on d.enter()
const dep = require('some-dep');
dep.method(); // Uh-oh! This method doesn't actually exist. is problematic if the module That's what I understood from
|
That's because domains take a multi-tenant environment and reduce it to a single-tenant error processor. Entering one domain should not exit another, a domain should only care about its own state transitions. The model should be redesigned so multiple domains can listen to errors from the same code and just have a top-level domain that handles the "default" behaviour of the "uncaughtException" event. Whenever other domains beyond the top-level one are created, the top-level one could just turn its handler off. 🤔 |
dcf31b9
to
fb98235
Compare
Rebased as #31930 has landed now. |
My 2 cents: if no one comes with a better name (#31945 (comment)), Update. A crazy idea: we could rename |
I'm fine with As for the |
The name must be about starting propagation. Focusing on the nature of the store instead of the started mechanism would be a logical mistake: a store holding mechanism should not spread a payload differently based on its nature. As for this PR reducing the need for patching in an APM/RASP context. It seems to me that implementer would still need to patch the |
Agreed that it should communicates that it's "starting" something, which is why I've stated that I don't have a strong feeling/intuition of what exactly the naming should be, just that I'm a little bit uncomfortable with the current enter/exit naming. As for needing to patch |
It would be quite simple to add a listener in http module to notify any tool that a new server has been created to allow to add it's The big question is where to start: Allow such usecases in |
Exactly. That's why I propose to think a bit more and try to find better names for those methods. Another option that I came up with. Keep |
What about |
Sounds like a more intuitive naming than the current one to me. |
Or maybe dropping the “with” part, to be not too terribly verbose. 🤔 |
Ok new CI run is good landing. |
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the `run*(...)` methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a `'connection'` event to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures. PR-URL: #31945 Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
Landed in d368dcc |
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the `run*(...)` methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a `'connection'` event to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures. PR-URL: #31945 Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
Notable changes: * [[`ff58854dbe`](ff58854dbe)] - **(SEMVER-MINOR)** **fs**: return first folder made by mkdir recursive (Benjamin Coe) [#31530](#31530) * [[`258a80d3cc`](258a80d3cc)] - **(SEMVER-MINOR)** **src**: create a getter for kernel version (Juan José Arboleda) [#31732](#31732) * [[`4d5981be96`](4d5981be96)] - **(SEMVER-MINOR)** **async_hooks**: add sync enterWith to ALS (Stephen Belanger) [#31945](#31945) * [[`dd83bd266d`](dd83bd266d)] - **(SEMVER-MINOR)** **wasi**: add returnOnExit option (Colin Ihrig) [#32101](#32101) PR-URL: #32185
Notable changes: * async_hooks: - add sync enterWith to ALS (Stephen Belanger) #31945 * cli: - allow --jitless V8 flag in NODE\_OPTIONS (Andrew Neitsch) #32100 * fs: - return first folder made by mkdir recursive (Benjamin Coe) #31530 * n-api: - define release 6 (Gabriel Schulhof) #32058 * src: - create a getter for kernel version (Juan José Arboleda) #31732 * wasi: - add returnOnExit option (Colin Ihrig) #32101 PR-URL: #32185
Notable changes: * async_hooks: - add sync enterWith to ALS (Stephen Belanger) #31945 * cli: - allow --jitless V8 flag in NODE\_OPTIONS (Andrew Neitsch) #32100 * fs: - return first folder made by mkdir recursive (Benjamin Coe) #31530 * n-api: - define release 6 (Gabriel Schulhof) #32058 * src: - create a getter for kernel version (Juan José Arboleda) #31732 * wasi: - add returnOnExit option (Colin Ihrig) #32101 PR-URL: #32185
Notable changes: * async_hooks: - add sync enterWith to ALS (Stephen Belanger) #31945 * cli: - allow --jitless V8 flag in NODE\_OPTIONS (Andrew Neitsch) #32100 * fs: - return first folder made by mkdir recursive (Benjamin Coe) #31530 * n-api: - define release 6 (Gabriel Schulhof) #32058 * src: - create a getter for kernel version (Juan José Arboleda) #31732 * wasi: - add returnOnExit option (Colin Ihrig) #32101 PR-URL: #32185
Notable changes: * async_hooks: - add sync enterWith to ALS (Stephen Belanger) #31945 * cli: - allow --jitless V8 flag in NODE\_OPTIONS (Andrew Neitsch) #32100 * fs: - return first folder made by mkdir recursive (Benjamin Coe) #31530 * n-api: - define release 6 (Gabriel Schulhof) #32058 * src: - create a getter for kernel version (Juan José Arboleda) #31732 * wasi: - add returnOnExit option (Colin Ihrig) #32101 PR-URL: #32185
v12 backport: #32318 |
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the `run*(...)` methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a `'connection'` event to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures. PR-URL: nodejs#31945 Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the `run*(...)` methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a `'connection'` event to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures. PR-URL: nodejs#31945 Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the `run*(...)` methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a `'connection'` event to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures. PR-URL: #31945 Reviewed-By: Vladimir de Turckheim <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
This allows transitioning the entire following sync and async execution sub-tree to the given async storage context. With this one can be sure the context binding will remain for any following sync activity and all descending async execution whereas the
run*(...)
methods must wrap everything that is intended to exist within the context. This is helpful for scenarios such as prepending a'connection'
event handler to an http server which binds everything that occurs within each request to the given context. This is helpful for APMs to minimize the need for patching and especially adding closures.Depends on #31930
cc @vdeturckheim @puzpuzpuz @Flarna
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes