mirror of https://github.com/nodejs/node.git
lib: improve async_context_frame structure
PR-URL: https://github.com/nodejs/node/pull/54239 Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
parent
88760f1c30
commit
7366808b85
|
@ -894,8 +894,8 @@ added: REPLACEME
|
|||
|
||||
> Stability: 1 - Experimental
|
||||
|
||||
Enables the use of AsyncLocalStorage backed by AsyncContextFrame rather than
|
||||
the default implementation which relies on async\_hooks. This new model is
|
||||
Enables the use of [`AsyncLocalStorage`][] backed by `AsyncContextFrame` rather
|
||||
than the default implementation which relies on async\_hooks. This new model is
|
||||
implemented very differently and so could have differences in how context data
|
||||
flows within the application. As such, it is presently recommended to be sure
|
||||
your application behaviour is unaffected by this change before using it in
|
||||
|
@ -3472,6 +3472,7 @@ node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12
|
|||
[`--print`]: #-p---print-script
|
||||
[`--redirect-warnings`]: #--redirect-warningsfile
|
||||
[`--require`]: #-r---require-module
|
||||
[`AsyncLocalStorage`]: async_context.md#class-asynclocalstorage
|
||||
[`Buffer`]: buffer.md#class-buffer
|
||||
[`CRYPTO_secure_malloc_init`]: https://www.openssl.org/docs/man3.0/man3/CRYPTO_secure_malloc_init.html
|
||||
[`NODE_OPTIONS`]: #node_optionsoptions
|
||||
|
|
|
@ -280,7 +280,7 @@ module.exports = {
|
|||
// Public API
|
||||
get AsyncLocalStorage() {
|
||||
return AsyncContextFrame.enabled ?
|
||||
require('internal/async_local_storage/native') :
|
||||
require('internal/async_local_storage/async_context_frame') :
|
||||
require('internal/async_local_storage/async_hooks');
|
||||
},
|
||||
createHook,
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
ObjectSetPrototypeOf,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
getContinuationPreservedEmbedderData,
|
||||
setContinuationPreservedEmbedderData,
|
||||
|
@ -7,28 +11,17 @@ const {
|
|||
|
||||
let enabled_;
|
||||
|
||||
class AsyncContextFrame extends Map {
|
||||
constructor(store, data) {
|
||||
super(AsyncContextFrame.current());
|
||||
this.set(store, data);
|
||||
}
|
||||
|
||||
class ActiveAsyncContextFrame {
|
||||
static get enabled() {
|
||||
enabled_ ??= require('internal/options')
|
||||
.getOptionValue('--experimental-async-context-frame');
|
||||
return enabled_;
|
||||
return true;
|
||||
}
|
||||
|
||||
static current() {
|
||||
if (this.enabled) {
|
||||
return getContinuationPreservedEmbedderData();
|
||||
}
|
||||
return getContinuationPreservedEmbedderData();
|
||||
}
|
||||
|
||||
static set(frame) {
|
||||
if (this.enabled) {
|
||||
setContinuationPreservedEmbedderData(frame);
|
||||
}
|
||||
setContinuationPreservedEmbedderData(frame);
|
||||
}
|
||||
|
||||
static exchange(frame) {
|
||||
|
@ -41,6 +34,37 @@ class AsyncContextFrame extends Map {
|
|||
const frame = this.current();
|
||||
frame?.disable(store);
|
||||
}
|
||||
}
|
||||
|
||||
function checkEnabled() {
|
||||
const enabled = require('internal/options')
|
||||
.getOptionValue('--experimental-async-context-frame');
|
||||
|
||||
// If enabled, swap to active prototype so we don't need to check status
|
||||
// on every interaction with the async context frame.
|
||||
if (enabled) {
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
ObjectSetPrototypeOf(AsyncContextFrame, ActiveAsyncContextFrame);
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
class AsyncContextFrame extends Map {
|
||||
constructor(store, data) {
|
||||
super(AsyncContextFrame.current());
|
||||
this.set(store, data);
|
||||
}
|
||||
|
||||
static get enabled() {
|
||||
enabled_ ??= checkEnabled();
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
static current() {}
|
||||
static set(frame) {}
|
||||
static exchange(frame) {}
|
||||
static disable(store) {}
|
||||
|
||||
disable(store) {
|
||||
this.delete(store);
|
||||
|
|
|
@ -44,7 +44,7 @@ const { AsyncResource } = require('async_hooks');
|
|||
|
||||
const AsyncContextFrame = require('internal/async_context_frame');
|
||||
|
||||
const async_context_frame = Symbol('asyncContextFrame');
|
||||
const async_context_frame = Symbol('kAsyncContextFrame');
|
||||
|
||||
// *Must* match Environment::TickInfo::Fields in src/env.h.
|
||||
const kHasTickScheduled = 0;
|
||||
|
|
|
@ -124,7 +124,7 @@ let debug = require('internal/util/debuglog').debuglog('timer', (fn) => {
|
|||
|
||||
const AsyncContextFrame = require('internal/async_context_frame');
|
||||
|
||||
const async_context_frame = Symbol('asyncContextFrame');
|
||||
const async_context_frame = Symbol('kAsyncContextFrame');
|
||||
|
||||
// *Must* match Environment::ImmediateInfo::Fields in src/env.h.
|
||||
const kCount = 0;
|
||||
|
|
|
@ -27,8 +27,8 @@ AsyncResource::AsyncResource(Isolate* isolate,
|
|||
|
||||
AsyncResource::~AsyncResource() {
|
||||
CHECK_NOT_NULL(env_);
|
||||
env_->RemoveAsyncResourceContextFrame(reinterpret_cast<std::uintptr_t>(this));
|
||||
EmitAsyncDestroy(env_, async_context_);
|
||||
env_->RemoveAsyncResourceContextFrame(reinterpret_cast<std::uintptr_t>(this));
|
||||
}
|
||||
|
||||
MaybeLocal<Value> AsyncResource::MakeCallback(Local<Function> callback,
|
||||
|
|
Loading…
Reference in New Issue