1
1
# Async Hooks
2
2
3
-
4
3
> Stability: 1 - Experimental
5
4
6
-
7
5
The ` async-hooks ` module provides an API to register callbacks tracking the
8
6
lifetime of asynchronous resources created inside a Node.js application.
7
+ It can be accessed using ` require('async-hooks') ` .
9
8
10
9
## Terminology
11
10
12
- An async resource represents either a "handle" or a "request" .
11
+ An async resource represents either a _ handle _ or a _ request _ .
13
12
14
13
Handles are a reference to a system resource. Some resources are a simple
15
14
identifier. For example, file system handles are represented by a file
@@ -27,7 +26,7 @@ writing data to disk.
27
26
28
27
### Overview
29
28
30
- Here is a simple overview of the public API. All of this API is explained in
29
+ Following is a simple overview of the public API. All of this API is explained in
31
30
more detail further down.
32
31
33
32
``` js
@@ -38,7 +37,7 @@ const cid = async_hooks.currentId();
38
37
39
38
// Return the id of the handle responsible for triggering the callback of the
40
39
// current execution scope to fire.
41
- const tid = aysnc_hooks .triggerId ();
40
+ const tid = async_hooks .triggerId ();
42
41
43
42
// Create a new AsyncHook instance. All of these callbacks are optional.
44
43
const asyncHook = async_hooks .createHook ({ init, before, after, destroy });
@@ -78,6 +77,12 @@ function destroy(id) { }
78
77
79
78
#### ` async_hooks.createHook(callbacks) `
80
79
80
+ <!-- YAML
81
+ added: REPLACEME
82
+ -->
83
+
84
+ * ` callbacks ` {Object} the callbacks to register
85
+
81
86
Registers functions to be called for different lifetime events of each async
82
87
operation.
83
88
The callbacks ` init() ` /` before() ` /` after() ` /` destroy() ` are registered via an
@@ -87,14 +92,16 @@ lifetime of the `AsyncWrap` C++ class. These callbacks will also be called to
87
92
emulate the lifetime of handles and requests that do not fit this model. For
88
93
example, ` HTTPParser ` instances are recycled to improve performance. Therefore the
89
94
` destroy() ` callback is called manually after a connection is done using
90
- it, just before it's placed back into the unused resource pool.
95
+ it, just before it is placed back into the unused resource pool.
91
96
92
97
All callbacks are optional. So, for example, if only resource cleanup needs to
93
98
be tracked then only the ` destroy() ` callback needs to be passed. The
94
99
specifics of all functions that can be passed to ` callbacks ` is in the section
95
100
` Hook Callbacks ` .
96
101
97
- ** Error Handling** : If any ` AsyncHook ` callbacks throw, the application will
102
+ ##### Error Handling
103
+
104
+ If any ` AsyncHook ` callbacks throw, the application will
98
105
print the stack trace and exit. The exit path does follow that of any uncaught
99
106
exception. However ` 'exit' ` callbacks will still fire unless the application
100
107
is run with ` --abort-on-uncaught-exception ` , in which case a stack trace will
@@ -141,7 +148,7 @@ destructor calls are emulated.
141
148
##### ` init(id, type, triggerId, resource) `
142
149
143
150
* ` id ` {number} a unique id for the async resource
144
- * ` type ` {String } the type of the async resource
151
+ * ` type ` {string } the type of the async resource
145
152
* ` triggerId ` {number} the unique id of the async resource in whose
146
153
execution context this async resource was created
147
154
* ` resource ` {Object} reference to the resource representing the async operation,
@@ -169,7 +176,7 @@ The `type` is a String that represents the type of resource that caused
169
176
Some examples include ` TCP ` , ` GetAddrInfo ` and ` HTTPParser ` . Users will be able
170
177
to define their own ` type ` when using the public embedder API.
171
178
172
- ** Note:* * It is possible to have type name collisions. Embedders are recommended
179
+ * Note:* It is possible to have type name collisions. Embedders are recommended
173
180
to use unique prefixes per module to prevent collisions when listening to the
174
181
hooks.
175
182
@@ -181,7 +188,7 @@ The following is a simple demonstration of this:
181
188
``` js
182
189
const async_hooks = require (' async_hooks' );
183
190
184
- asyns_hooks .createHook ({
191
+ async_hooks .createHook ({
185
192
init (id , type , triggerId ) {
186
193
const cId = async_hooks .currentId ();
187
194
process ._rawDebug (` ${ type} (${ id} ): trigger: ${ triggerId} scope: ${ cId} ` );
@@ -272,13 +279,13 @@ First notice that `scope` and the value returned by `currentId()` are always
272
279
the same. That's because ` currentId() ` simply returns the value of the
273
280
current execution context; which is defined by ` before() ` and ` after() ` calls.
274
281
275
- Now if we only use ` scope ` to graph resource allocation we get the following:
282
+ Now only using ` scope ` to graph resource allocation results in the following:
276
283
277
284
```
278
285
TTYWRAP(6) -> Timeout(4) -> TIMERWRAP(5) -> TickObject(3) -> root(1)
279
286
```
280
287
281
- The ` TCPWRAP ` isn't part of this graph; evne though it was the reason for
288
+ The ` TCPWRAP ` isn't part of this graph; even though it was the reason for
282
289
` console.log() ` being called. This is because binding to a port without a
283
290
hostname is actually synchronous, but to maintain a completely asynchronous API
284
291
the user's callback is placed in a ` process.nextTick() ` .
@@ -323,9 +330,9 @@ Some resources, such as `HTTPParser`, are not actually destructed but instead
323
330
placed in an unused resource pool to be used later. For these ` destroy() ` will
324
331
be called just before the resource is placed on the unused resource pool.
325
332
326
- ** Note:* * Some resources depend on GC for cleanup. So if a reference is made to
333
+ * Note:* Some resources depend on GC for cleanup. So if a reference is made to
327
334
the ` resource ` object passed to ` init() ` it's possible that ` destroy() ` is
328
- never called. Causing a memory leak in the application. Of course if you know
335
+ never called. Causing a memory leak in the application. Of course if
329
336
the resource doesn't depend on GC then this isn't an issue.
330
337
331
338
#### ` async_hooks.currentId() `
@@ -343,17 +350,17 @@ fs.open(path, (err, fd) => {
343
350
```
344
351
345
352
It is important to note that the id returned fom ` currentId() ` is related to
346
- execution timing. Not causality (which is covered by ` triggerId() ` ). For
353
+ execution timing. Not causality (which is covered by ` triggerId() ` ). For
347
354
example:
348
355
349
356
``` js
350
- const server = net .createServer (function onconnection (conn ) {
357
+ const server = net .createServer (function onConnection (conn ) {
351
358
// Returns the id of the server, not of the new connection. Because the
352
359
// on connection callback runs in the execution scope of the server's
353
360
// MakeCallback().
354
361
async_hooks .currentId ();
355
362
356
- }).listen (port, function onlistening () {
363
+ }).listen (port, function onListening () {
357
364
// Returns the id of a TickObject (i.e. process.nextTick()) because all
358
365
// callbacks passed to .listen() are wrapped in a nextTick().
359
366
async_hooks .currentId ();
@@ -390,7 +397,7 @@ this a JavaScript API is provided.
390
397
391
398
### ` class AsyncEvent() `
392
399
393
- The class ` AsyncEvent ` was designed to be extended from for embedder's async
400
+ The class ` AsyncEvent ` was designed to be extended by the embedder's async
394
401
resources. Using this users can easily trigger the lifetime events of their
395
402
own resources.
396
403
@@ -424,7 +431,7 @@ asyncEvent.triggerId();
424
431
#### ` AsyncEvent(type[, triggerId]) `
425
432
426
433
* arguments
427
- * ` type ` {String } the type of ascycn event
434
+ * ` type ` {string } the type of ascycn event
428
435
* ` triggerId ` {number} the id of the execution context that created this async
429
436
event
430
437
* Returns {AsyncEvent} A reference to ` asyncHook ` .
@@ -433,7 +440,7 @@ Example usage:
433
440
434
441
``` js
435
442
class DBQuery extends AsyncEvent {
436
- construtor (db ) {
443
+ constructor (db ) {
437
444
this .db = db;
438
445
}
439
446
@@ -454,15 +461,15 @@ class DBQuery extends AsyncEvent {
454
461
455
462
#### ` asyncEvent.emitBefore() `
456
463
457
- * Returns {Undefined }
464
+ * Returns {undefined }
458
465
459
466
Call all ` before() ` hooks and let them know a new asynchronous execution
460
467
context is being entered. If nested calls to ` emitBefore() ` are made the stack
461
468
of ` id ` s will be tracked and properly unwound.
462
469
463
470
#### ` asyncEvent.emitAfter() `
464
471
465
- * Returns {Undefined }
472
+ * Returns {undefined }
466
473
467
474
Call all ` after() ` hooks. If nested calls to ` emitBefore() ` were made then make
468
475
sure the stack is unwound properly. Otherwise an error will be thrown.
@@ -474,7 +481,7 @@ this.
474
481
475
482
#### ` asyncEvent.emitDestroy() `
476
483
477
- * Returns {Undefined }
484
+ * Returns {undefined }
478
485
479
486
Call all ` destroy() ` hooks. This should only ever be called once. An error will
480
487
be thrown if it is called more than once. This ** must** be manually called. If
@@ -556,10 +563,10 @@ responsible for the newly created resource being instantiated. For example:
556
563
#### ` async_hooks.emitInit(id, type[, triggerId][, resource]) `
557
564
558
565
* ` id ` {number} Generated by calling ` newId() `
559
- * ` type ` {String }
566
+ * ` type ` {string }
560
567
* ` triggerId ` {number} ** Default:** ` currentId() `
561
568
* ` resource ` {Object}
562
- * Returns {Undefined }
569
+ * Returns {undefined }
563
570
564
571
Emit that a resource is being initialized. ` id ` should be a value returned by
565
572
` async_hooks.newId() ` . Usage will probably be as follows:
@@ -585,7 +592,7 @@ constructor.
585
592
586
593
* ` id ` {number} Generated by ` newId() `
587
594
* ` triggerId ` {number}
588
- * Returns {Undefined }
595
+ * Returns {undefined }
589
596
590
597
Notify ` before() ` hooks that the resource is about to enter its execution call
591
598
stack. If the ` triggerId ` of the resource is different from ` id ` then pass
@@ -610,7 +617,7 @@ MyThing.prototype.done = function done() {
610
617
#### ` async_hooks.emitAfter(id) `
611
618
612
619
* ` id ` {number} Generated by ` newId() `
613
- * Returns {Undefined }
620
+ * Returns {undefined }
614
621
615
622
Notify ` after() ` hooks that the resource is exiting its execution call stack.
616
623
@@ -629,23 +636,23 @@ after # Foo <- Should be called after Bar
629
636
after # Bar
630
637
```
631
638
632
- ** Note:* * It is not necessary to wrap the callback in a try/finally and force
639
+ * Note:* It is not necessary to wrap the callback in a try/finally and force
633
640
emitAfter() if the callback throws. That is automatically handled by the
634
641
fatal exception handler.
635
642
636
643
#### ` async_hooks.emitDestroy(id) `
637
644
638
645
* ` id ` {number} Generated by ` newId() `
639
- * Returns {Undefined }
646
+ * Returns {undefined }
640
647
641
- Notify hooks that a resource is being destroyed (or being moved to the free'd
648
+ Notify hooks that a resource is being destroyed (or being moved to the freed
642
649
resource pool).
643
650
644
651
#### ` async_hooks.triggerIdScope(triggerId, callback) `
645
652
646
653
* ` triggerId ` {number}
647
654
* ` callback ` {Function}
648
- * Returns {Undefined }
655
+ * Returns {undefined }
649
656
650
657
All resources created during the execution of ` callback ` will be given
651
658
` triggerId ` . Unless it was otherwise 1) passed in as an argument to
0 commit comments