/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
lib/internal/trace_events_async_hooks.js
97 строк
3 KB
Chengzhong Wu
lib: add perfetto support
24 июл 2026, 17:00
24 июл 2026, 17:00
5022b94
Код
Авторство
О чём код?
'use strict'; const { ObjectKeys, SafeMap, SafeSet, Symbol, } = primordials; const { trace, nodeTraceEventCategory, kAsyncBegin, kAsyncEnd, kSyncBegin, kSyncEnd, } = require('internal/trace_events'); const async_wrap = internalBinding('async_wrap'); const async_hooks = require('async_hooks'); const kTraceEventCategory = nodeTraceEventCategory('node.async_hooks'); const kEnabled = Symbol('enabled'); // It is faster to emit traceEvents directly from C++. Thus, this happens // in async_wrap.cc. However, events emitted from the JavaScript API or the // Embedder C++ API can't be emitted from async_wrap.cc. Thus they are // emitted using the JavaScript API. To prevent emitting the same event // twice the async_wrap.Providers list is used to filter the events. const nativeProviders = new SafeSet(ObjectKeys(async_wrap.Providers)); const typeMemory = new SafeMap(); // Promises are not AsyncWrap resources so they should emit trace_events here. nativeProviders.delete('PROMISE'); function createHook() { // In traceEvents it is not only the id but also the name that needs to be // repeated. Since async_hooks doesn't expose the provider type in the // non-init events, use a map to manually map the asyncId to the type name. const hook = async_hooks.createHook({ init(asyncId, type, triggerAsyncId, resource) { if (nativeProviders.has(type)) return; typeMemory.set(asyncId, type); trace(kAsyncBegin, kTraceEventCategory, type, asyncId, { triggerAsyncId, executionAsyncId: async_hooks.executionAsyncId(), }); }, before(asyncId) { const type = typeMemory.get(asyncId); if (type === undefined) return; trace(kSyncBegin, kTraceEventCategory, `${type}_CALLBACK`, asyncId); }, after(asyncId) { const type = typeMemory.get(asyncId); if (type === undefined) return; trace(kSyncEnd, kTraceEventCategory, `${type}_CALLBACK`, asyncId); }, destroy(asyncId) { const type = typeMemory.get(asyncId); if (type === undefined) return; trace(kAsyncEnd, kTraceEventCategory, type, asyncId); // Cleanup asyncId to type map typeMemory.delete(asyncId); }, }); return { enable() { if (this[kEnabled]) return; this[kEnabled] = true; hook.enable(); }, disable() { if (!this[kEnabled]) return; this[kEnabled] = false; hook.disable(); typeMemory.clear(); }, }; } exports.createHook = createHook;