11'use strict' ;
22
3- exports . setup = function ( traceEvents , traceEventCategory ) {
4- const { trace } = traceEvents ;
5- const async_wrap = process . binding ( 'async_wrap' ) ;
6- const async_hooks = require ( 'async_hooks' ) ;
3+ const { internalBinding } = require ( 'internal/bootstrap/loaders' ) ;
4+ const { trace } = internalBinding ( 'trace_events' ) ;
5+ const async_wrap = process . binding ( 'async_wrap' ) ;
6+ const async_hooks = require ( 'async_hooks' ) ;
7+ const { SafeMap, SafeSet } = require ( 'internal/safe_globals' ) ;
78
8- // Use small letters such that chrome://tracing groups by the name.
9- // The behavior is not only useful but the same as the events emitted using
10- // the specific C++ macros.
11- const BEFORE_EVENT = 'b' . charCodeAt ( 0 ) ;
12- const END_EVENT = 'e' . charCodeAt ( 0 ) ;
9+ // Use small letters such that chrome://tracing groups by the name.
10+ // The behavior is not only useful but the same as the events emitted using
11+ // the specific C++ macros.
12+ const kBeforeEvent = 'b' . charCodeAt ( 0 ) ;
13+ const kEndEvent = 'e' . charCodeAt ( 0 ) ;
14+ const kTraceEventCategory = 'node,node.async_hooks' ;
1315
16+ const kEnabled = Symbol ( 'enabled' ) ;
17+
18+ // It is faster to emit traceEvents directly from C++. Thus, this happens
19+ // in async_wrap.cc. However, events emitted from the JavaScript API or the
20+ // Embedder C++ API can't be emitted from async_wrap.cc. Thus they are
21+ // emitted using the JavaScript API. To prevent emitting the same event
22+ // twice the async_wrap.Providers list is used to filter the events.
23+ const nativeProviders = new SafeSet ( Object . keys ( async_wrap . Providers ) ) ;
24+ const typeMemory = new SafeMap ( ) ;
25+
26+ function createHook ( ) {
1427 // In traceEvents it is not only the id but also the name that needs to be
1528 // repeated. Since async_hooks doesn't expose the provider type in the
1629 // non-init events, use a map to manually map the asyncId to the type name.
17- const typeMemory = new Map ( ) ;
1830
19- // It is faster to emit traceEvents directly from C++. Thus, this happens
20- // in async_wrap.cc. However, events emitted from the JavaScript API or the
21- // Embedder C++ API can't be emitted from async_wrap.cc. Thus they are
22- // emitted using the JavaScript API. To prevent emitting the same event
23- // twice the async_wrap.Providers list is used to filter the events.
24- const nativeProviders = new Set ( Object . keys ( async_wrap . Providers ) ) ;
25-
26- async_hooks . createHook ( {
31+ const hook = async_hooks . createHook ( {
2732 init ( asyncId , type , triggerAsyncId , resource ) {
2833 if ( nativeProviders . has ( type ) ) return ;
2934
3035 typeMemory . set ( asyncId , type ) ;
31- trace ( BEFORE_EVENT , traceEventCategory ,
36+ trace ( kBeforeEvent , kTraceEventCategory ,
3237 type , asyncId ,
3338 {
3439 triggerAsyncId,
@@ -40,24 +45,43 @@ exports.setup = function(traceEvents, traceEventCategory) {
4045 const type = typeMemory . get ( asyncId ) ;
4146 if ( type === undefined ) return ;
4247
43- trace ( BEFORE_EVENT , traceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
48+ trace ( kBeforeEvent , kTraceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
4449 } ,
4550
4651 after ( asyncId ) {
4752 const type = typeMemory . get ( asyncId ) ;
4853 if ( type === undefined ) return ;
4954
50- trace ( END_EVENT , traceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
55+ trace ( kEndEvent , kTraceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
5156 } ,
5257
5358 destroy ( asyncId ) {
5459 const type = typeMemory . get ( asyncId ) ;
5560 if ( type === undefined ) return ;
5661
57- trace ( END_EVENT , traceEventCategory , type , asyncId ) ;
62+ trace ( kEndEvent , kTraceEventCategory , type , asyncId ) ;
5863
5964 // cleanup asyncId to type map
6065 typeMemory . delete ( asyncId ) ;
6166 }
62- } ) . enable ( ) ;
63- } ;
67+ } ) ;
68+
69+ return {
70+ enable ( ) {
71+ if ( this [ kEnabled ] )
72+ return ;
73+ this [ kEnabled ] = true ;
74+ hook . enable ( ) ;
75+ } ,
76+
77+ disable ( ) {
78+ if ( ! this [ kEnabled ] )
79+ return ;
80+ this [ kEnabled ] = false ;
81+ hook . disable ( ) ;
82+ typeMemory . clear ( ) ;
83+ }
84+ } ;
85+ }
86+
87+ module . exports = createHook ( ) ;
0 commit comments