Skip to content

Commit 9a2461e

Browse files
author
Stephen Belanger
committed
async_hooks: switch between native and context hooks correctly
🤦 Might help if I remember to disable the _other_ promise hook implementation when switching between them... Fixes #38814 Fixes #38815
1 parent 21f5a56 commit 9a2461e

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/internal/async_hooks.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ function updatePromiseHookMode() {
357357
wantPromiseHook = true;
358358
if (destroyHooksExist()) {
359359
enablePromiseHook();
360+
setPromiseHooks(undefined, undefined, undefined, undefined);
360361
} else {
362+
disablePromiseHook();
361363
setPromiseHooks(
362364
initHooksExist() ? promiseInitHook : undefined,
363365
promiseBeforeHook,
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const async_hooks = require('async_hooks');
5+
6+
// Regression test for:
7+
// - https://github.com/nodejs/node/issues/38814
8+
// - https://github.com/nodejs/node/issues/38815
9+
10+
const expected = [
11+
['init', 2, 'PROMISE', 1],
12+
['init', 3, 'PROMISE', 1],
13+
['promiseResolve', 3],
14+
['promiseResolve', 2],
15+
['before', 2],
16+
['init', 4, 'PROMISE', 3],
17+
['after', 2],
18+
['before', 4],
19+
['promiseResolve', 2],
20+
['promiseResolve', 4],
21+
['after', 4],
22+
];
23+
24+
const actual = [];
25+
26+
// Only init to start context-based promise hook
27+
async_hooks.createHook({
28+
init() { }
29+
}).enable();
30+
31+
// With destroy, this should switch to native
32+
// and disable context - based promise hook
33+
async_hooks.createHook({
34+
init(asyncId, type, triggerAsyncId) {
35+
actual.push([ 'init', asyncId, type, triggerAsyncId ]);
36+
},
37+
before(asyncId) {
38+
actual.push([ 'before', asyncId ]);
39+
},
40+
after(asyncId) {
41+
actual.push([ 'after', asyncId ]);
42+
},
43+
promiseResolve(asyncId) {
44+
actual.push([ 'promiseResolve', asyncId ]);
45+
},
46+
destroy(asyncId) {
47+
actual.push([ 'destroy', asyncId ]);
48+
}
49+
}).enable();
50+
51+
async function main() {
52+
return Promise.resolve();
53+
}
54+
55+
main();
56+
57+
process.on('exit', () => {
58+
for (const event of expected) {
59+
assert.deepStrictEqual(actual.shift(), event);
60+
}
61+
});

0 commit comments

Comments
 (0)