docs: documenting async hooks features #13287
Conversation
|
LGTM modulo typos (if it helps I can fix them myself and push to this PR) |
|
|
||
| If any `AsyncHook` callbacks throw, the application will print the stack trace | ||
| and exit. The exit path does follow that of an uncaught exception but | ||
| all `uncaughtException` listeners are removed, thus forceing the process to |
addaleax
May 29, 2017
Member
typo: forceing → forcing
typo: forceing → forcing
| If any `AsyncHook` callbacks throw, the application will print the stack trace | ||
| and exit. The exit path does follow that of an uncaught exception but | ||
| all `uncaughtException` listeners are removed, thus forceing the process to | ||
| exit. The `'exit'` callbacks will still call unless the application is run with |
addaleax
May 29, 2017
Member
call → be called
call → be called
|
|
||
| ##### Printing in AsyncHooks callbacks | ||
|
|
||
| Because printing to the console is an asynchronous operations `console.log()` |
addaleax
May 29, 2017
Member
typo: operations → operation
typo: operations → operation
| ##### Printing in AsyncHooks callbacks | ||
|
|
||
| Because printing to the console is an asynchronous operations `console.log()` | ||
| will cause the AsyncHooks callbacks to write. Using `console.log()` or similar |
addaleax
May 29, 2017
Member
write → be called
write → be called
|
|
||
| The `type` is a string that represents the type of resource that caused | ||
| `init()` to call. Generally it will be the name of the resource's constructor. | ||
| The resource types provided by the build in Node.js modules are: |
addaleax
May 29, 2017
Member
typo: build in → built-in
typo: build in → built-in
| the user's callback is placed in a `process.nextTick()`. | ||
|
|
||
| The graph only shows **when** a resource was created. Not **why**. So to track | ||
| the **why** use `triggerId`. |
addaleax
May 29, 2017
Member
typos: created. Not **why**. So to → created, not **why**, so to
typos: created. Not **why**. So to → created, not **why**, so to
| For example: | ||
|
|
||
| ```js | ||
| const server = net.createServer(conn => { |
addaleax
May 29, 2017
Member
I think we run the linter on docs now, so this might need to be (conn) instead of conn
I think we run the linter on docs now, so this might need to be (conn) instead of conn
| * Returns {undefined} | ||
|
|
||
| Call all `before()` callbacks and let them know a new asynchronous execution | ||
| context is being entered. If nested calls to `emitBefore()` are made the stack |
addaleax
May 29, 2017
Member
comma after made
comma after made
|
|
||
| * Returns {undefined} | ||
|
|
||
| Call all `after()` callbacks. If nested calls to `emitBefore()` were made then |
addaleax
May 29, 2017
Member
comma after made
comma after made
| make sure the stack is unwound properly. Otherwise an error will be thrown. | ||
|
|
||
| If the user's callback throws an exception then `emitAfter()` will | ||
| automatically be called for all `id`'s on the stack if the error is handled by |
addaleax
May 29, 2017
Member
remove the apostrophe (`id`'s → `id`s)
remove the apostrophe (`id`'s → `id`s)
that would be awesome as I will go to bed soon. For minor things, I find this much more helpful. |
|
|
||
| An asynchronous resource represents an object with an associated callback. | ||
| This callback may be called multiple times, for example, the `connection` event | ||
| in `net.createServer`, or just a single time like in `fs.open`. A resource |
mikesherov
May 29, 2017
A word is missing somewhere in this sentence: a resource can also be closed the callback is called
A word is missing somewhere in this sentence: a resource can also be closed the callback is called
AndreasMadsen
May 30, 2017
Author
Member
Thanks.
a resource can also be closed the before callback is called
Thanks.
a resource can also be closed the before callback is called
|
Looking good. My bad on not seeing most of these before now. |
| An asynchronous resource represents an object with an associated callback. | ||
| This callback may be called multiple times, for example, the `connection` event | ||
| in `net.createServer`, or just a single time like in `fs.open`. A resource | ||
| can also be closed before the callback is called. AsyncHooks does not |
trevnorris
May 30, 2017
Contributor
The class name is actually AsyncHook. Reason the module is called async_hooks (plural) was to match events and timers (both plural but their class names aren't).
The class name is actually AsyncHook. Reason the module is called async_hooks (plural) was to match events and timers (both plural but their class names aren't).
trevnorris
May 30, 2017
Contributor
A resource can also be closed before the callback is called.
It looks like we're abstracting the difference between a request and an handle? Personally that would make me sad. Spent a lot of time precisely describing the difference between the two. :P
A resource can also be closed before the callback is called.
It looks like we're abstracting the difference between a request and an handle? Personally that would make me sad. Spent a lot of time precisely describing the difference between the two. :P
AndreasMadsen
May 31, 2017
Author
Member
There are zero references to request and handle in the of the documentation (except for the previous terminology section). If request and handle are to be included, it should be described exactly how those concepts are visible in async_hooks.
see: #12953 (comment)
There are zero references to request and handle in the of the documentation (except for the previous terminology section). If request and handle are to be included, it should be described exactly how those concepts are visible in async_hooks.
see: #12953 (comment)
| // destroy() is called when an AsyncWrap instance is destroyed. | ||
| function destroy(id) { } | ||
| ``` |
trevnorris
May 30, 2017
Contributor
Should we just drop this whole section and replace it with common patterns and questions? e.g. "Handling events only once" in Events.
There are some corrections this section needs, but not going to comment b/c it may possibly be removed.
Should we just drop this whole section and replace it with common patterns and questions? e.g. "Handling events only once" in Events.
There are some corrections this section needs, but not going to comment b/c it may possibly be removed.
AndreasMadsen
Jun 1, 2017
Author
Member
We definitely need a common patterns section, but let's not do it in this PR. When we write that I'm fine with removing this.
We definitely need a common patterns section, but let's not do it in this PR. When we write that I'm fine with removing this.
|
|
||
| Registers functions to be called for different lifetime events of each async | ||
| operation. | ||
| The callbacks `init()`/`before()`/`after()`/`destroy()` are registered via an |
trevnorris
May 30, 2017
Contributor
why the early return after "operation."? Looks like this should be a single paragraph.
why the early return after "operation."? Looks like this should be a single paragraph.
trevnorris
May 30, 2017
Contributor
I'd either simplify this to:
The callbacks init()/before()/after()/destroy() are called for the respective asynchronous event during a resource's lifetime.
Or take the time to explain what "registered" means:
The callbacks init()/before()/after()/destroy() are registered to a global list of hooks that are called for each respective asynchronous event during a resource's lifetime.
I'd either simplify this to:
The callbacks
init()/before()/after()/destroy()are called for the respective asynchronous event during a resource's lifetime.
Or take the time to explain what "registered" means:
The callbacks
init()/before()/after()/destroy()are registered to a global list of hooks that are called for each respective asynchronous event during a resource's lifetime.
| All callbacks are optional. So, for example, if only resource cleanup needs to | ||
| be tracked then only the `destroy()` callback needs to be passed. The | ||
| specifics of all functions that can be passed to `callbacks` is in the section | ||
| [`Hook Callbacks`][]. |
trevnorris
May 30, 2017
Contributor
Possibly add that enabling an empty AsyncHook instance is a noop. Or add this in the enable() API section.
Possibly add that enabling an empty AsyncHook instance is a noop. Or add this in the enable() API section.
| track of what caused the asynchronous operation using the information | ||
| provided by AsyncHooks itself. The logging should then be skipped when | ||
| it was the logging itself that caused AsyncHooks callback to call. By | ||
| doing this the otherwise infinite recursion is broken. |
trevnorris
May 30, 2017
Contributor
I presented the idea elsewhere, but what about just disabling the ability to call a hook while other hooks are running? That would solve this easily (and I think it's reasonable that we don't need to give async statistics while the async hooks are running).
I presented the idea elsewhere, but what about just disabling the ability to call a hook while other hooks are running? That would solve this easily (and I think it's reasonable that we don't need to give async statistics while the async hooks are running).
|
|
||
| The `init()` hook will trigger when an `AsyncResource` is instantiated. | ||
|
|
||
| It is important that before/after calls are unwined |
trevnorris
May 30, 2017
Contributor
We should make the document consistent between before()/after() or before/after or before/after. No personal preference, but is more aesthetically pleasing.
We should make the document consistent between before()/after() or before/after or before/after. No personal preference, but is more aesthetically pleasing.
trevnorris
May 30, 2017
Contributor
Instead:
It is important that before/after calls are unwound in the same order [...]
Instead:
It is important that
before/aftercalls are unwound in the same order [...]
| // Return the trigger ID for the AsyncResource instance. | ||
| asyncResource.triggerId(); | ||
| ``` |
trevnorris
May 30, 2017
Contributor
If this is supposed to be an API overview then it should probably have the sub-heading that says that. But it may also want to be removed, like I discussed above or the other similar section.
If this is supposed to be an API overview then it should probably have the sub-heading that says that. But it may also want to be removed, like I discussed above or the other similar section.
| * arguments | ||
| * `type` {string} the type of ascyc event | ||
| * `triggerId` {number} the ID of the execution context that created this async | ||
| event |
trevnorris
May 30, 2017
Contributor
Add that the default is currentId()
Add that the default is currentId()
AndreasMadsen
May 31, 2017
Author
Member
Again, we can't document details in the summary.
Again, we can't document details in the summary.
| never called, causing a memory leak in the application. Of course if | ||
| the resource doesn't depend on GC then this isn't an issue. | ||
|
|
||
| #### `async_hooks.currentId()` |
trevnorris
May 30, 2017
Contributor
I think this should either be changed to asyncId() or currentAsyncId() (to follow the change for the function argument names). If the latter then triggerId() should probably be changed to currentTriggerId(). I'm down to hear alternatives, but would like to see it be more explicit and uniform. (sorry, my bad)
I think this should either be changed to asyncId() or currentAsyncId() (to follow the change for the function argument names). If the latter then triggerId() should probably be changed to currentTriggerId(). I'm down to hear alternatives, but would like to see it be more explicit and uniform. (sorry, my bad)
AndreasMadsen
May 31, 2017
Author
Member
This would have been a really nice comment to make before node.js 8 was released.
/cc @addaleax
This would have been a really nice comment to make before node.js 8 was released.
/cc @addaleax
addaleax
May 31, 2017
Member
Yeah, it would be nice to have done that before, but I don’t think it needs to be a big deal.
currentAsyncId() and currentTriggerId() sound fine to me. We can always make the old names (non-enumerable?) aliases for those, so we don’t break any existing code.
Yeah, it would be nice to have done that before, but I don’t think it needs to be a big deal.
currentAsyncId() and currentTriggerId() sound fine to me. We can always make the old names (non-enumerable?) aliases for those, so we don’t break any existing code.
AndreasMadsen
Jun 1, 2017
Author
Member
I'm okay with renaming it, but I think it would be much better to do that in another PR.
I'm okay with renaming it, but I think it would be much better to do that in another PR.
| ```js | ||
| class DBQuery extends AsyncResource { | ||
| constructor(db) { | ||
| super(); |
trevnorris
May 30, 2017
Contributor
May want to do super('DBQuery'). Since this would throw. from source:
if (typeof type !== 'string' || type.length <= 0)
throw new TypeError('type must be a string with length > 0');
May want to do super('DBQuery'). Since this would throw. from source:
if (typeof type !== 'string' || type.length <= 0)
throw new TypeError('type must be a string with length > 0');|
@trevnorris thanks for the review. I'm not going to fix any of this in the next 24 hours. I have addressed the comments I don't understand. |
|
@AndreasMadsen No worries. I'll get to those you did leave comments on. |
|
@trevnorris please take a look.
|
|
Much thanks for getting this ready. |
|
Landed in 126170a (fixed up 2 linter complaints while landing.) |
Author: Thorsten Lorenz <thlorenz@gmx.de> Author: Andreas Madsen <amwebdk@gmail.com> PR-URL: #13287 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
|
This does not land cleanly in LTS. Please feel free to manually backport. Please also feel free to replace do-not-land if it is being backported |
Checklist
Affected core subsystem(s)
This is a continuation on #12953 it should "fix" all the suggestions.
It took me 3 hours fix all the issues, so I would like if nits are done by you in a followup PR I simply don't have this much time. Also please be very specific with the suggestions, as in replace "this" with "this".