async_hooks: add using scopes to AsyncLocalStorage#61674
async_hooks: add using scopes to AsyncLocalStorage#61674Qard wants to merge 1 commit intonodejs:mainfrom
Conversation
af2ad3e to
d8e83aa
Compare
|
I guess this replaces #58104 right? |
|
Ah, yes. Forgot that one existed. 😅 |
Adds support for using scope = storage.withScope(data) to do the equivalent of a storage.run(data, fn) with using syntax. This enables avoiding unnecessary closures.
Failed to start CI⚠ No approving reviews found ✘ Refusing to run CI on potentially unsafe PRhttps://github.com/nodejs/node/actions/runs/21678728231 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #61674 +/- ##
==========================================
+ Coverage 89.74% 89.75% +0.01%
==========================================
Files 674 675 +1
Lines 204389 204428 +39
Branches 39280 39284 +4
==========================================
+ Hits 183424 183480 +56
- Misses 13264 13265 +1
+ Partials 7701 7683 -18
🚀 New features to boost your workflow:
|
This comment was marked as outdated.
This comment was marked as outdated.
| scope[Symbol.dispose](); | ||
| assert.strictEqual(storage.getStore(), undefined); | ||
|
|
||
| // Double dispose should be idempotent |
There was a problem hiding this comment.
Maybe adapt to following to better verify that second call does nothing:
storage.enterWith('test2');
assert.strictEqual(storage.getStore(), 'test2');
// Double dispose should be idempotent
scope[Symbol.dispose]();
assert.strictEqual(storage.getStore(), 'test2');
| const asyncLocalStorage = new AsyncLocalStorage(); | ||
|
|
||
| { | ||
| using scope = asyncLocalStorage.withScope('my-store'); |
There was a problem hiding this comment.
| using scope = asyncLocalStorage.withScope('my-store'); | |
| using _ = asyncLocalStorage.withScope('my-store'); |
I think this is the usual guideline if unused. Feel free to ignore.
| const asyncLocalStorage = new AsyncLocalStorage(); | ||
|
|
||
| { | ||
| using scope = asyncLocalStorage.withScope('my-store'); |
There was a problem hiding this comment.
| using scope = asyncLocalStorage.withScope('my-store'); | |
| using _ = asyncLocalStorage.withScope('my-store'); |
| const asyncLocalStorage = new AsyncLocalStorage(); | ||
|
|
||
| try { | ||
| using scope = asyncLocalStorage.withScope('my-store'); |
There was a problem hiding this comment.
| using scope = asyncLocalStorage.withScope('my-store'); | |
| using _ = asyncLocalStorage.withScope('my-store'); |
| const asyncLocalStorage = new AsyncLocalStorage(); | ||
|
|
||
| try { | ||
| using scope = asyncLocalStorage.withScope('my-store'); |
There was a problem hiding this comment.
| using scope = asyncLocalStorage.withScope('my-store'); | |
| using _ = asyncLocalStorage.withScope('my-store'); |
|
|
||
| Creates a disposable scope that enters the given store and automatically | ||
| restores the previous store value when the scope is disposed. This method is | ||
| designed to work with JavaScript's explicit resource management (`using` syntax). |
There was a problem hiding this comment.
We should document the caveat that this cause side effects outside of an async function scope if this is called before the first await:
async function foo() {
using value = als.withScope(newValue);
await 0;
}
foo() // no await
al's.getStore() // value changed.There was a problem hiding this comment.
Yep.
This is also exactly why I had previously suggested that AsyncContext create context boundaries around the initial segment of async functions too in order to make the set/get model work.
In my opinion the entire async function execution model is wrong until the first segment either has its own context or is made async the way the rest of the function is. It was a strange decision making execution of that initial segment synchronous, especially given that thrown errors in that segment are not synchronous. That whole part of the spec is full of landmines. 😬
Adds support for
using scope = storage.withScope(data)to do the equivalent of astorage.run(data, fn)with using syntax. This enables avoiding unnecessary closures.cc @nodejs/diagnostics