Skip to content

Commit 1a2cf66

Browse files
AndreasMadsenGeorge Adams
authored and
George Adams
committed
async_hooks: remove promise object from resource
While it doesn't make any difference now. In the future PromiseHooks could be refactored to provide an asyncId instead of the promise object. That would make escape analysis on promises possible. Escape analysis on promises could lead to a more efficient destroy hook, if provide by PromiseHooks as well. But at the very least would allow the destroy hook to be emitted earlier. The destroy hook not being emitted on promises frequent enough is a known and reported issue. See #14446 and Jeff-Lewis/cls-hooked#11. While all this is speculation for now, it all depends on the promise object not being a part of the PromiseWrap resource object. Ref: #14446 Ref: nodejs/diagnostics#188 PR-URL: #23443 Refs: #14446 Refs: nodejs/diagnostics#188 Reviewed-By: Benedikt Meurer <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: George Adams <[email protected]>
1 parent 561e30d commit 1a2cf66

6 files changed

+5
-34
lines changed

doc/api/async_hooks.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,7 @@ currently not considered public, but using the Embedder API, users can provide
301301
and document their own resource objects. For example, such a resource object
302302
could contain the SQL query being executed.
303303

304-
In the case of Promises, the `resource` object will have `promise` property
305-
that refers to the `Promise` that is being initialized, and an
304+
In the case of Promises, the `resource` object will have an
306305
`isChainedPromise` property, set to `true` if the promise has a parent promise,
307306
and `false` otherwise. For example, in the case of `b = a.then(handler)`, `a` is
308307
considered a parent `Promise` of `b`. Here, `b` is considered a chained promise.

lib/domain.js

-7
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@ const asyncHook = createHook({
5555
// if this operation is created while in a domain, let's mark it
5656
pairing.set(asyncId, process.domain);
5757
resource.domain = process.domain;
58-
if (resource.promise !== undefined &&
59-
resource.promise instanceof Promise) {
60-
// resource.promise instanceof Promise make sure that the
61-
// promise comes from the same context
62-
// see https://github.com/nodejs/node/issues/15673
63-
resource.promise.domain = process.domain;
64-
}
6558
}
6659
},
6760
before(asyncId) {

src/async_wrap.cc

+2-14
Original file line numberDiff line numberDiff line change
@@ -185,16 +185,13 @@ class PromiseWrap : public AsyncWrap {
185185
SET_MEMORY_INFO_NAME(PromiseWrap)
186186
SET_SELF_SIZE(PromiseWrap)
187187

188-
static constexpr int kPromiseField = 1;
189-
static constexpr int kIsChainedPromiseField = 2;
190-
static constexpr int kInternalFieldCount = 3;
188+
static constexpr int kIsChainedPromiseField = 1;
189+
static constexpr int kInternalFieldCount = 2;
191190

192191
static PromiseWrap* New(Environment* env,
193192
Local<Promise> promise,
194193
PromiseWrap* parent_wrap,
195194
bool silent);
196-
static void GetPromise(Local<String> property,
197-
const PropertyCallbackInfo<Value>& info);
198195
static void getIsChainedPromise(Local<String> property,
199196
const PropertyCallbackInfo<Value>& info);
200197
};
@@ -205,7 +202,6 @@ PromiseWrap* PromiseWrap::New(Environment* env,
205202
bool silent) {
206203
Local<Object> object = env->promise_wrap_template()
207204
->NewInstance(env->context()).ToLocalChecked();
208-
object->SetInternalField(PromiseWrap::kPromiseField, promise);
209205
object->SetInternalField(PromiseWrap::kIsChainedPromiseField,
210206
parent_wrap != nullptr ?
211207
v8::True(env->isolate()) :
@@ -215,11 +211,6 @@ PromiseWrap* PromiseWrap::New(Environment* env,
215211
return new PromiseWrap(env, object, silent);
216212
}
217213

218-
void PromiseWrap::GetPromise(Local<String> property,
219-
const PropertyCallbackInfo<Value>& info) {
220-
info.GetReturnValue().Set(info.Holder()->GetInternalField(kPromiseField));
221-
}
222-
223214
void PromiseWrap::getIsChainedPromise(Local<String> property,
224215
const PropertyCallbackInfo<Value>& info) {
225216
info.GetReturnValue().Set(
@@ -315,9 +306,6 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) {
315306
Local<ObjectTemplate> promise_wrap_template = ctor->InstanceTemplate();
316307
promise_wrap_template->SetInternalFieldCount(
317308
PromiseWrap::kInternalFieldCount);
318-
promise_wrap_template->SetAccessor(
319-
FIXED_ONE_BYTE_STRING(env->isolate(), "promise"),
320-
PromiseWrap::GetPromise);
321309
promise_wrap_template->SetAccessor(
322310
FIXED_ONE_BYTE_STRING(env->isolate(), "isChainedPromise"),
323311
PromiseWrap::getIsChainedPromise);

test/parallel/test-async-hooks-promise-enable-disable.js

-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const common = require('../common');
44
const assert = require('assert');
55
const async_hooks = require('async_hooks');
66
const EXPECTED_INITS = 2;
7-
let p_resource = null;
87
let p_er = null;
98
let p_inits = 0;
109

@@ -23,7 +22,6 @@ const mustCallInit = common.mustCall(function init(id, type, tid, resource) {
2322
if (type !== 'PROMISE')
2423
return;
2524
p_inits++;
26-
p_resource = resource.promise;
2725
}, EXPECTED_INITS);
2826

2927
const hook = async_hooks.createHook({
@@ -36,7 +34,6 @@ new Promise(common.mustCall((res) => {
3634
})).then(common.mustCall((val) => {
3735
hook.enable().enable();
3836
const p = new Promise((res) => res(val));
39-
assert.strictEqual(p, p_resource);
4037
hook.disable();
4138
return p;
4239
})).then(common.mustCall((val2) => {

test/parallel/test-async-hooks-promise.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ async_hooks.createHook({
2121
}).enable();
2222

2323
const a = Promise.resolve(42);
24-
const b = a.then(common.mustCall());
24+
a.then(common.mustCall());
2525

2626
assert.strictEqual(initCalls[0].triggerId, 1);
2727
assert.strictEqual(initCalls[0].resource.isChainedPromise, false);
28-
assert.strictEqual(initCalls[0].resource.promise, a);
2928
assert.strictEqual(initCalls[1].triggerId, initCalls[0].id);
3029
assert.strictEqual(initCalls[1].resource.isChainedPromise, true);
31-
assert.strictEqual(initCalls[1].resource.promise, b);

test/parallel/test-domain-promise.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ const vm = require('vm');
5050
d2.run(common.mustCall(() => {
5151
p.then(common.mustCall((v) => {
5252
assert.strictEqual(process.domain, d2);
53-
assert.strictEqual(p.domain, d1);
5453
}));
5554
}));
5655
}
@@ -64,9 +63,8 @@ const vm = require('vm');
6463
}));
6564

6665
d2.run(common.mustCall(() => {
67-
p.then(p.domain.bind(common.mustCall((v) => {
66+
p.then(d1.bind(common.mustCall((v) => {
6867
assert.strictEqual(process.domain, d1);
69-
assert.strictEqual(p.domain, d1);
7068
})));
7169
}));
7270
}
@@ -83,7 +81,6 @@ const vm = require('vm');
8381
d2.run(common.mustCall(() => {
8482
p.then(common.mustCall((v) => {
8583
assert.strictEqual(process.domain, d2);
86-
assert.strictEqual(p.domain, d1);
8784
}));
8885
}));
8986
}));
@@ -100,7 +97,6 @@ const vm = require('vm');
10097
d2.run(common.mustCall(() => {
10198
p.catch(common.mustCall((v) => {
10299
assert.strictEqual(process.domain, d2);
103-
assert.strictEqual(p.domain, d1);
104100
}));
105101
}));
106102
}

0 commit comments

Comments
 (0)