@@ -73,7 +73,11 @@ function destroy(asyncId) { }
73
73
added: REPLACEME
74
74
-->
75
75
76
- * ` callbacks ` {Object} the callbacks to register
76
+ * ` callbacks ` {Object} the [ Hook Callbacks] [ ] to register
77
+ * ` init ` {Function} The [ ` init ` callback] [ ] .
78
+ * ` before ` {Function} The [ ` before ` callback] [ ] .
79
+ * ` after ` {Function} The [ ` after ` callback] [ ] .
80
+ * ` destroy ` {Function} The [ ` destroy ` callback] [ ] .
77
81
* Returns: ` {AsyncHook} ` instance used for disabling and enabling hooks
78
82
79
83
Registers functions to be called for different lifetime events of each async
@@ -87,6 +91,31 @@ be tracked then only the `destroy` callback needs to be passed. The
87
91
specifics of all functions that can be passed to ` callbacks ` is in the section
88
92
[ ` Hook Callbacks ` ] [ ] .
89
93
94
+ ``` js
95
+ const async_hooks = require (' async_hooks' );
96
+
97
+ const asyncHook = async_hooks .createHook ({
98
+ init (asyncId , type , triggerAsyncId , resource ) { },
99
+ destroy (asyncId ) { }
100
+ });
101
+ ```
102
+
103
+ Note that the callbacks will be inherited via the prototype chain:
104
+
105
+ ``` js
106
+ class MyAsyncCallbacks {
107
+ init (asyncId , type , triggerAsyncId , resource ) { }
108
+ destroy (asyncId ) {}
109
+ }
110
+
111
+ class MyAddedCallbacks extends MyAsyncCallbacks {
112
+ before (asyncId ) { }
113
+ after (asyncId ) { }
114
+ }
115
+
116
+ const asyncHook = async_hooks .createHook (new MyAddedCallbacks ());
117
+ ```
118
+
90
119
##### Error Handling
91
120
92
121
If any ` AsyncHook ` callbacks throw, the application will print the stack trace
@@ -187,11 +216,12 @@ require('net').createServer().listen(function() { this.close(); });
187
216
clearTimeout (setTimeout (() => {}, 10 ));
188
217
```
189
218
190
- Every new resource is assigned a unique ID.
219
+ Every new resource is assigned an ID that is unique within the scope of the
220
+ current process.
191
221
192
222
###### ` type `
193
223
194
- The ` type ` is a string that represents the type of resource that caused
224
+ The ` type ` is a string identifying the type of resource that caused
195
225
` init ` to be called. Generally, it will correspond to the name of the
196
226
resource's constructor.
197
227
@@ -214,8 +244,8 @@ when listening to the hooks.
214
244
215
245
###### ` triggerId `
216
246
217
- ` triggerAsyncId ` is the ` asyncId ` of the resource that caused (or "triggered") the
218
- new resource to initialize and that caused ` init ` to call. This is different
247
+ ` triggerAsyncId ` is the ` asyncId ` of the resource that caused (or "triggered")
248
+ the new resource to initialize and that caused ` init ` to call. This is different
219
249
from ` async_hooks.executionAsyncId() ` that only shows * when* a resource was
220
250
created, while ` triggerAsyncId ` shows * why* a resource was created.
221
251
@@ -253,26 +283,27 @@ propagating what resource is responsible for the new resource's existence.
253
283
254
284
###### ` resource `
255
285
256
- ` resource ` is an object that represents the actual resource. This can contain
257
- useful information such as the hostname for the ` GETADDRINFOREQWRAP ` resource
258
- type, which will be used when looking up the ip for the hostname in
259
- ` net.Server.listen ` . The API for getting this information is currently not
260
- considered public, but using the Embedder API users can provide and document
261
- their own resource objects. Such as resource object could for example contain
262
- the SQL query being executed.
286
+ ` resource ` is an object that represents the actual async resource that has
287
+ been initialized. This can contain useful information that can vary based on
288
+ the value of ` type ` . For instance, for the ` GETADDRINFOREQWRAP ` resource type,
289
+ ` resource ` provides the hostname used when looking up the IP address for the
290
+ hostname in ` net.Server.listen() ` . The API for accessing this information is
291
+ currently not considered public, but using the Embedder API, users can provide
292
+ and document their own resource objects. Such a resource object could for
293
+ example contain the SQL query being executed.
263
294
264
295
In the case of Promises, the ` resource ` object will have ` promise ` property
265
296
that refers to the Promise that is being initialized, and a ` parentId ` property
266
- that equals the ` asyncId ` of a parent Promise, if there is one, and
267
- ` undefined ` otherwise. For example, in the case of ` b = a.then(handler) ` ,
268
- ` a ` is considered a parent Promise of ` b ` .
297
+ set to the ` asyncId ` of a parent Promise, if there is one, and ` undefined `
298
+ otherwise. For example, in the case of ` b = a.then(handler) ` , ` a ` is considered
299
+ a parent Promise of ` b ` .
269
300
270
301
* Note* : In some cases the resource object is reused for performance reasons,
271
302
it is thus not safe to use it as a key in a ` WeakMap ` or add properties to it.
272
303
273
- ###### asynchronous context example
304
+ ###### Asynchronous context example
274
305
275
- Below is another example with additional information about the calls to
306
+ The following is an example with additional information about the calls to
276
307
` init ` between the ` before ` and ` after ` calls, specifically what the
277
308
callback to ` listen() ` will look like. The output formatting is slightly more
278
309
elaborate to make calling context easier to see.
@@ -348,10 +379,10 @@ Only using `execution` to graph resource allocation results in the following:
348
379
TTYWRAP(6) -> Timeout(4) -> TIMERWRAP(5) -> TickObject(3) -> root(1)
349
380
```
350
381
351
- The ` TCPWRAP ` isn't part of this graph; even though it was the reason for
382
+ The ` TCPWRAP ` is not part of this graph; even though it was the reason for
352
383
` console.log() ` being called. This is because binding to a port without a
353
- hostname is actually synchronous, but to maintain a completely asynchronous API
354
- the user's callback is placed in a ` process.nextTick() ` .
384
+ hostname is a * synchronous* operation , but to maintain a completely asynchronous
385
+ API the user's callback is placed in a ` process.nextTick() ` .
355
386
356
387
The graph only shows * when* a resource was created, not * why* , so to track
357
388
the * why* use ` triggerAsyncId ` .
@@ -369,9 +400,10 @@ resource about to execute the callback.
369
400
370
401
The ` before ` callback will be called 0 to N times. The ` before ` callback
371
402
will typically be called 0 times if the asynchronous operation was cancelled
372
- or for example if no connections are received by a TCP server. Asynchronous
373
- like the TCP server will typically call the ` before ` callback multiple times,
374
- while other operations like ` fs.open() ` will only call it once.
403
+ or, for example, if no connections are received by a TCP server. Persistent
404
+ asynchronous resources like a TCP server will typically call the ` before `
405
+ callback multiple times, while other operations like ` fs.open() ` will only call
406
+ it only once.
375
407
376
408
377
409
##### ` after(asyncId) `
@@ -381,30 +413,33 @@ while other operations like `fs.open()` will only call it once.
381
413
Called immediately after the callback specified in ` before ` is completed.
382
414
383
415
* Note:* If an uncaught exception occurs during execution of the callback then
384
- ` after ` will run after the ` 'uncaughtException' ` event is emitted or a
416
+ ` after ` will run * after* the ` 'uncaughtException' ` event is emitted or a
385
417
` domain ` 's handler runs.
386
418
387
419
388
420
##### ` destroy(asyncId) `
389
421
390
422
* ` asyncId ` {number}
391
423
392
- Called after the resource corresponding to ` asyncId ` is destroyed. It is also called
393
- asynchronously from the embedder API ` emitDestroy() ` .
424
+ Called after the resource corresponding to ` asyncId ` is destroyed. It is also
425
+ called asynchronously from the embedder API ` emitDestroy() ` .
394
426
395
- * Note:* Some resources depend on GC for cleanup, so if a reference is made to
396
- the ` resource ` object passed to ` init ` it's possible that ` destroy ` is
397
- never called, causing a memory leak in the application. Of course if
398
- the resource doesn't depend on GC then this isn't an issue.
427
+ * Note:* Some resources depend on garbage collection for cleanup, so if a
428
+ reference is made to the ` resource ` object passed to ` init ` it is possible that
429
+ ` destroy ` will never be called, causing a memory leak in the application. If
430
+ the resource does not depend on garbage collection, then this will not be an
431
+ issue.
399
432
400
433
#### ` async_hooks.executionAsyncId() `
401
434
402
- * Returns {number} the ` asyncId ` of the current execution context. Useful to track
403
- when something calls.
435
+ * Returns {number} the ` asyncId ` of the current execution context. Useful to
436
+ track when something calls.
404
437
405
438
For example:
406
439
407
440
``` js
441
+ const async_hooks = require (' async_hooks' );
442
+
408
443
console .log (async_hooks .executionAsyncId ()); // 1 - bootstrap
409
444
fs .open (path, ' r' , (err , fd ) => {
410
445
console .log (async_hooks .executionAsyncId ()); // 6 - open()
@@ -453,10 +488,9 @@ const server = net.createServer((conn) => {
453
488
454
489
## JavaScript Embedder API
455
490
456
- Library developers that handle their own I/O, a connection pool, or
457
- callback queues will need to hook into the AsyncWrap API so that all the
458
- appropriate callbacks are called. To accommodate this a JavaScript API is
459
- provided.
491
+ Library developers that handle their own asychronous resources performing tasks
492
+ like I/O, connection pooling, or managing callback queues may use the ` AsyncWrap `
493
+ JavaScript API so that all the appropriate callbacks are called.
460
494
461
495
### ` class AsyncResource() `
462
496
@@ -466,9 +500,9 @@ own resources.
466
500
467
501
The ` init ` hook will trigger when an ` AsyncResource ` is instantiated.
468
502
469
- It is important that ` before ` /` after ` calls are unwound
503
+ * Note * : It is important that ` before ` /` after ` calls are unwound
470
504
in the same order they are called. Otherwise an unrecoverable exception
471
- will occur and node will abort.
505
+ will occur and the process will abort.
472
506
473
507
The following is an overview of the ` AsyncResource ` API.
474
508
@@ -499,9 +533,9 @@ asyncResource.triggerAsyncId();
499
533
#### ` AsyncResource(type[, triggerAsyncId]) `
500
534
501
535
* arguments
502
- * ` type ` {string} the type of ascyc event
503
- * ` triggerAsyncId ` {number} the ID of the execution context that created this async
504
- event
536
+ * ` type ` {string} the type of async event
537
+ * ` triggerAsyncId ` {number} the ID of the execution context that created this
538
+ async event
505
539
506
540
Example usage:
507
541
@@ -531,9 +565,9 @@ class DBQuery extends AsyncResource {
531
565
532
566
* Returns {undefined}
533
567
534
- Call all ` before ` callbacks and let them know a new asynchronous execution
535
- context is being entered. If nested calls to ` emitBefore() ` are made, the stack
536
- of ` asyncId ` s will be tracked and properly unwound.
568
+ Call all ` before ` callbacks to notify that a new asynchronous execution context
569
+ is being entered. If nested calls to ` emitBefore() ` are made, the stack of
570
+ ` asyncId ` s will be tracked and properly unwound.
537
571
538
572
#### ` asyncResource.emitAfter() `
539
573
@@ -542,9 +576,9 @@ of `asyncId`s will be tracked and properly unwound.
542
576
Call all ` after ` callbacks. If nested calls to ` emitBefore() ` were made, then
543
577
make sure the stack is unwound properly. Otherwise an error will be thrown.
544
578
545
- If the user's callback throws an exception then ` emitAfter() ` will
546
- automatically be called for all ` asyncId ` s on the stack if the error is handled by
547
- a domain or ` 'uncaughtException' ` handler.
579
+ If the user's callback throws an exception, ` emitAfter() ` will automatically be
580
+ called for all ` asyncId ` s on the stack if the error is handled by a domain or
581
+ ` 'uncaughtException' ` handler.
548
582
549
583
#### ` asyncResource.emitDestroy() `
550
584
@@ -564,4 +598,8 @@ never be called.
564
598
* Returns {number} the same ` triggerAsyncId ` that is passed to the ` AsyncResource `
565
599
constructor.
566
600
601
+ [ `after` callback ] : #async_hooks_after_asyncid
602
+ [ `before` callback ] : #async_hooks_before_asyncid
603
+ [ `destroy` callback ] : #async_hooks_before_asyncid
567
604
[ `Hook Callbacks` ] : #async_hooks_hook_callbacks
605
+ [ `init` callback ] : #async_hooks_init_asyncid_type_triggerasyncid_resource
0 commit comments