-
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
The store when using enterWith/exitWith in asyncLocalStorage is not "stacked" #36683
Comments
@nodejs/async_hooks |
@giltayar
What you faced in your snippet is a consequence of the described behavior, i.e. the context will always be asyncLocalStorage.run({depth: 1}, () => {
assert.deepStrictEqual(asyncLocalStorage.getStore(), {depth: 1})
asyncLocalStorage.run({depth: 2}, () => {
// new scope (`als.run()` acts as if it would be a new async call in the chain)
assert.deepStrictEqual(asyncLocalStorage.getStore(), {depth: 2})
})
// here we're in the scope of the previous async call
assert.deepStrictEqual(asyncLocalStorage.getStore(), {depth: 1})
}) Also, |
@puzpuzpuz I thought this is maybe the defined behavior, but it wasn't clear from the documentation. If this is the defined behavior, then, yes, this issue can be closed. I'll wait a bit to see if anybody else has any input, and close it in a day or two if not. Thanks for the clarification! |
Looks like the doc are a bit misleading. I've created #36705 as an attempt to make things more clear. |
PR-URL: nodejs#36705 Refs: nodejs#36683 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Rich Trott <[email protected]>
PR-URL: #36705 Refs: #36683 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Rich Trott <[email protected]>
Yeah, ALS is not in any way stacked. The current storage value is stored directly on the current resource, so it's a one-to-one relationship--any history would be lost. |
This comment threw me off a little when I first read it, so expanded the OP's nested var { AsyncLocalStorage } = require("async_hooks");
var assert = require("assert");
const asyncLocalStorage = new AsyncLocalStorage();
asyncLocalStorage.run({ depth: 1 }, () => {
assert.deepStrictEqual(asyncLocalStorage.getStore(), { depth: 1 });
asyncLocalStorage.run({ depth: 2 }, () => {
setTimeout(() => {
assert.deepStrictEqual(asyncLocalStorage.getStore(), { depth: 2 });
}, 2000);
});
asyncLocalStorage.run({ depth: 3 }, () => {
setTimeout(() => {
assert.deepStrictEqual(asyncLocalStorage.getStore(), { depth: 3 });
}, 1000);
});
assert.deepStrictEqual(asyncLocalStorage.getStore(), { depth: 1 });
}); What does this tell us? Even though you cannot directly access the values that were previously bound to the specific |
They only form a stack in the sense that the code itself forms a stack. When you do While it may not be especially clear, what this means is that multiple sets of context data are not stored and therefore accessible in descending async code. Only the data of the nearest run will be reachable. The |
PR-URL: #36705 Refs: #36683 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Rich Trott <[email protected]>
What steps will reproduce the bug?
I expected the following program to work:
But it fails in the line after the marked
****
. The reason I expected it to work is because I assumed thatenter/exit
has the same "stacked" semantics asrun
, in that entering twice and exiting once will give me the store of the first enter. Unfortunately, the store I get after the firstexit
isundefined
.How often does it reproduce? Is there a required condition?
Consistent. Always.
What is the expected behavior?
The program should pass without error. See above for why.
What do you see instead?
A failure of the code:
Additional information
This also fails in v14.15.1
The text was updated successfully, but these errors were encountered: