Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
inspector: skip promise hook in the inspector async hook
Instead of filtering out promises in the async hooks added
for async task tracking, add an internal path to skip adding
the promise hook completely for the inspector async hook.
The actual user-land promise tracking is already handled by
V8 inspector. This prevents the internal promise hook from
showing up and creating unnecessary noise when stepping into
async execution in the inspector.
  • Loading branch information
joyeecheung committed Feb 20, 2025
commit ce8a375cdd2712cdbfa994b5b0b7bec9392d4055
7 changes: 5 additions & 2 deletions lib/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const AsyncContextFrame = require('internal/async_context_frame');
// Get functions
// For userland AsyncResources, make sure to emit a destroy event when the
// resource gets gced.
const { registerDestroyHook } = internal_async_hooks;
const { registerDestroyHook, kNoPromiseHook } = internal_async_hooks;
const {
asyncWrap,
executionAsyncId,
Expand Down Expand Up @@ -90,6 +90,7 @@ class AsyncHook {
this[after_symbol] = after;
this[destroy_symbol] = destroy;
this[promise_resolve_symbol] = promiseResolve;
this[kNoPromiseHook] = false;
}

enable() {
Expand Down Expand Up @@ -120,7 +121,9 @@ class AsyncHook {
enableHooks();
}

updatePromiseHookMode();
if (!this[kNoPromiseHook]) {
updatePromiseHookMode();
}

return this;
}
Expand Down
15 changes: 3 additions & 12 deletions lib/internal/inspector_async_hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function lazyHookCreation() {
const inspector = internalBinding('inspector');
const { createHook } = require('async_hooks');
config = internalBinding('config');
const { kNoPromiseHook } = require('internal/async_hooks');

hook = createHook({
init(asyncId, type, triggerAsyncId, resource) {
Expand All @@ -19,32 +20,22 @@ function lazyHookCreation() {
// in https://github.com/nodejs/node/pull/13870#discussion_r124515293,
// this should be fine as long as we call asyncTaskCanceled() too.
const recurring = true;
if (type === 'PROMISE')
this.promiseIds.add(asyncId);
else
inspector.asyncTaskScheduled(type, asyncId, recurring);
inspector.asyncTaskScheduled(type, asyncId, recurring);
},

before(asyncId) {
if (this.promiseIds.has(asyncId))
return;
inspector.asyncTaskStarted(asyncId);
},

after(asyncId) {
if (this.promiseIds.has(asyncId))
return;
inspector.asyncTaskFinished(asyncId);
},

destroy(asyncId) {
if (this.promiseIds.has(asyncId))
return this.promiseIds.delete(asyncId);
inspector.asyncTaskCanceled(asyncId);
},
});

hook.promiseIds = new SafeSet();
hook[kNoPromiseHook] = true;
}

function enable() {
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-inspector-async-call-stack.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function verifyAsyncHookEnabled(message) {
assert.strictEqual(async_hook_fields[kTotals], 4,
`${async_hook_fields[kTotals]} !== 4: ${message}`);
const promiseHooks = getPromiseHooks();
assert.notDeepStrictEqual(
assert.deepStrictEqual( // Inspector async hooks should not enable promise hooks
promiseHooks, emptyPromiseHooks,
`${message}: promise hooks ${inspect(promiseHooks)}`
);
Expand Down