Skip to content

Commit

Permalink
async_hooks: switch between native and context hooks correctly
Browse files Browse the repository at this point in the history
🤦 Might help if I remember to disable the _other_ promise
hook implementation when switching between them...

Fixes nodejs#38814
Fixes nodejs#38815
  • Loading branch information
Stephen Belanger committed Jun 3, 2021
1 parent 21f5a56 commit a86542e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/internal/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,9 @@ function updatePromiseHookMode() {
wantPromiseHook = true;
if (destroyHooksExist()) {
enablePromiseHook();
setPromiseHooks(undefined, undefined, undefined, undefined);
} else {
disablePromiseHook();
setPromiseHooks(
initHooksExist() ? promiseInitHook : undefined,
promiseBeforeHook,
Expand Down
59 changes: 59 additions & 0 deletions test/parallel/test-async-hooks-correctly-switch-promise-hook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';
require('../common');
const assert = require('assert');
const async_hooks = require('async_hooks');

// Regression test for:
// - https://github.com/nodejs/node/issues/38814
// - https://github.com/nodejs/node/issues/38815

const expected = [
['init', 2, 'PROMISE', 1],
['init', 3, 'PROMISE', 1],
['promiseResolve', 3],
['promiseResolve', 2],
['before', 2],
['init', 4, 'PROMISE', 3],
['after', 2],
['before', 4],
['promiseResolve', 2],
['promiseResolve', 4],
['after', 4],
];

const actual = [];

// Only init to start context-based promise hook
async_hooks.createHook({
init() { }
}).enable();

// With destroy, this should switch to native
// and disable context - based promise hook
async_hooks.createHook({
init(asyncId, type, triggerAsyncId) {
actual.push([ 'init', asyncId, type, triggerAsyncId ]);
},
before(asyncId) {
actual.push([ 'before', asyncId ]);
},
after(asyncId) {
actual.push([ 'after', asyncId ]);
},
promiseResolve(asyncId) {
actual.push([ 'promiseResolve', asyncId ]);
},
destroy(asyncId) {
actual.push([ 'destroy', asyncId ]);
}
}).enable();

async function main() {
return Promise.resolve();
}

main();

process.on('exit', () => {
assert.deepStrictEqual(actual, expected);
});

0 comments on commit a86542e

Please sign in to comment.