async_hooks: fix default nextTick triggerAsyncId · nodejs/node@7b369d1 · GitHub
Skip to content

Commit 7b369d1

Browse files
AndreasMadsenaddaleax
authored andcommitted
async_hooks: fix default nextTick triggerAsyncId
In the case where triggerAsyncId is null it should default to the current executionAsyncId. This worked but as a side-effect the resource object was changed too. This fix also makes the null check more strict. EmitInitS is not a documented API, thus there is no reason to be flexible in its input. Ref: #13548 (comment) PR-URL: #14026 Reviewed-By: Refael Ackermann <refack@gmail.com>
1 parent 86c06c0 commit 7b369d1

5 files changed

Lines changed: 73 additions & 15 deletions

File tree

lib/async_hooks.js

Lines changed: 1 addition & 3 deletions

lib/internal/process/next_tick.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function setupNextTick() {
6060
// The needed emit*() functions.
6161
const { emitInit, emitBefore, emitAfter, emitDestroy } = async_hooks;
6262
// Grab the constants necessary for working with internal arrays.
63-
const { kInit, kBefore, kAfter, kDestroy, kAsyncUidCntr, kInitTriggerId } =
63+
const { kInit, kBefore, kAfter, kDestroy, kAsyncUidCntr } =
6464
async_wrap.constants;
6565
const { async_id_symbol, trigger_id_symbol } = async_wrap;
6666
var nextTickQueue = new NextTickQueue();
@@ -302,6 +302,10 @@ function setupNextTick() {
302302
if (process._exiting)
303303
return;
304304

305+
if (triggerAsyncId === null) {
306+
triggerAsyncId = async_hooks.initTriggerId();
307+
}
308+
305309
var args;
306310
switch (arguments.length) {
307311
case 2: break;
@@ -320,8 +324,5 @@ function setupNextTick() {
320324
++tickInfo[kLength];
321325
if (async_hook_fields[kInit] > 0)
322326
emitInit(asyncId, 'TickObject', triggerAsyncId, obj);
323-
324-
// The call to initTriggerId() was skipped, so clear kInitTriggerId.
325-
async_uid_fields[kInitTriggerId] = 0;
326327
}
327328
}

test/async-hooks/init-hooks.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ class ActivityCollector {
3434
this._logid = logid;
3535
this._logtype = logtype;
3636

37-
// register event handlers if provided
37+
// Register event handlers if provided
3838
this.oninit = typeof oninit === 'function' ? oninit : noop;
3939
this.onbefore = typeof onbefore === 'function' ? onbefore : noop;
4040
this.onafter = typeof onafter === 'function' ? onafter : noop;
4141
this.ondestroy = typeof ondestroy === 'function' ? ondestroy : noop;
4242

43-
// create the hook with which we'll collect activity data
43+
// Create the hook with which we'll collect activity data
4444
this._asyncHook = async_hooks.createHook({
4545
init: this._init.bind(this),
4646
before: this._before.bind(this),
@@ -106,10 +106,15 @@ class ActivityCollector {
106106
'\nExpected "destroy" to be called after "after"');
107107
}
108108
}
109+
if (!a.handleIsObject) {
110+
v('No resource object\n' + activityString(a) +
111+
'\nExpected "init" to be called with a resource object');
112+
}
109113
}
110114
if (violations.length) {
111-
console.error(violations.join('\n'));
112-
assert.fail(violations.length, 0, `Failed sanity checks: ${violations}`);
115+
console.error(violations.join('\n\n') + '\n');
116+
assert.fail(violations.length, 0,
117+
`${violations.length} failed sanity checks`);
113118
}
114119
}
115120

@@ -143,11 +148,11 @@ class ActivityCollector {
143148
_getActivity(uid, hook) {
144149
const h = this._activities.get(uid);
145150
if (!h) {
146-
// if we allowed handles without init we ignore any further life time
151+
// If we allowed handles without init we ignore any further life time
147152
// events this makes sense for a few tests in which we enable some hooks
148153
// later
149154
if (this._allowNoInit) {
150-
const stub = { uid, type: 'Unknown' };
155+
const stub = { uid, type: 'Unknown', handleIsObject: true };
151156
this._activities.set(uid, stub);
152157
return stub;
153158
} else {
@@ -163,7 +168,14 @@ class ActivityCollector {
163168
}
164169

165170
_init(uid, type, triggerAsyncId, handle) {
166-
const activity = { uid, type, triggerAsyncId };
171+
const activity = {
172+
uid,
173+
type,
174+
triggerAsyncId,
175+
// In some cases (e.g. Timeout) the handle is a function, thus the usual
176+
// `typeof handle === 'object' && handle !== null` check can't be used.
177+
handleIsObject: handle instanceof Object
178+
};
167179
this._stamp(activity, 'init');
168180
this._activities.set(uid, activity);
169181
this._maybeLog(uid, type, 'init');

test/async-hooks/test-emit-init.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ initHooks({
4646
})
4747
}).enable();
4848

49-
async_hooks.emitInit(expectedId, expectedType, expectedResource);
49+
async_hooks.emitInit(expectedId, expectedType, null, expectedResource);
Lines changed: 47 additions & 0 deletions

0 commit comments

Comments
 (0)