1
1
'use strict' ;
2
2
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' ) ;
7
8
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' ;
13
15
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 ( ) {
14
27
// In traceEvents it is not only the id but also the name that needs to be
15
28
// repeated. Since async_hooks doesn't expose the provider type in the
16
29
// non-init events, use a map to manually map the asyncId to the type name.
17
- const typeMemory = new Map ( ) ;
18
30
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 ( {
27
32
init ( asyncId , type , triggerAsyncId , resource ) {
28
33
if ( nativeProviders . has ( type ) ) return ;
29
34
30
35
typeMemory . set ( asyncId , type ) ;
31
- trace ( BEFORE_EVENT , traceEventCategory ,
36
+ trace ( kBeforeEvent , kTraceEventCategory ,
32
37
type , asyncId ,
33
38
{
34
39
triggerAsyncId,
@@ -40,24 +45,43 @@ exports.setup = function(traceEvents, traceEventCategory) {
40
45
const type = typeMemory . get ( asyncId ) ;
41
46
if ( type === undefined ) return ;
42
47
43
- trace ( BEFORE_EVENT , traceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
48
+ trace ( kBeforeEvent , kTraceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
44
49
} ,
45
50
46
51
after ( asyncId ) {
47
52
const type = typeMemory . get ( asyncId ) ;
48
53
if ( type === undefined ) return ;
49
54
50
- trace ( END_EVENT , traceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
55
+ trace ( kEndEvent , kTraceEventCategory , `${ type } _CALLBACK` , asyncId ) ;
51
56
} ,
52
57
53
58
destroy ( asyncId ) {
54
59
const type = typeMemory . get ( asyncId ) ;
55
60
if ( type === undefined ) return ;
56
61
57
- trace ( END_EVENT , traceEventCategory , type , asyncId ) ;
62
+ trace ( kEndEvent , kTraceEventCategory , type , asyncId ) ;
58
63
59
64
// cleanup asyncId to type map
60
65
typeMemory . delete ( asyncId ) ;
61
66
}
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