From 146538de65f40c52edc5a8bb359426a0f121a13d Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Thu, 4 Jun 2020 20:58:52 +0300 Subject: [PATCH] doc: improve async_hooks asynchronous context example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * use writeFile(1) everywhere to log * prettify execution id graph * add clearer explanation for TickObject presence * add causation graph via triggerAsyncId PR-URL: https://github.com/nodejs/node/pull/33730 Reviewed-By: Gerhard Stöbich Reviewed-By: Andrey Pechkurov Reviewed-By: James M Snell Reviewed-By: Vladimir de Turckheim --- doc/api/async_hooks.md | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index 7bbff4cddbce57..0471bc5ccef5ad 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -331,20 +331,17 @@ async_hooks.createHook({ }, before(asyncId) { const indentStr = ' '.repeat(indent); - fs.writeFileSync('log.out', - `${indentStr}before: ${asyncId}\n`, { flag: 'a' }); + fs.writeSync(process.stdout.fd, `${indentStr}before: ${asyncId}\n`); indent += 2; }, after(asyncId) { indent -= 2; const indentStr = ' '.repeat(indent); - fs.writeFileSync('log.out', - `${indentStr}after: ${asyncId}\n`, { flag: 'a' }); + fs.writeSync(process.stdout.fd, `${indentStr}after: ${asyncId}\n`); }, destroy(asyncId) { const indentStr = ' '.repeat(indent); - fs.writeFileSync('log.out', - `${indentStr}destroy: ${asyncId}\n`, { flag: 'a' }); + fs.writeSync(process.stdout.fd, `${indentStr}destroy: ${asyncId}\n`); }, }).enable(); @@ -380,16 +377,38 @@ the value of the current execution context; which is delineated by calls to Only using `execution` to graph resource allocation results in the following: ```console -Timeout(7) -> TickObject(6) -> root(1) + root(1) + ^ + | +TickObject(6) + ^ + | + Timeout(7) ``` The `TCPSERVERWRAP` is not part of this graph, even though it was the reason for `console.log()` being called. This is because binding to a port without a host name is a *synchronous* operation, but to maintain a completely asynchronous -API the user's callback is placed in a `process.nextTick()`. +API the user's callback is placed in a `process.nextTick()`. Which is why +`TickObject` is present in the output and is a 'parent' for `.listen()` +callback. The graph only shows *when* a resource was created, not *why*, so to track -the *why* use `triggerAsyncId`. +the *why* use `triggerAsyncId`. Which can be represented with the following +graph: + +```console + bootstrap(1) + | + ˅ +TCPSERVERWRAP(5) + | + ˅ + TickObject(6) + | + ˅ + Timeout(7) +``` ##### `before(asyncId)`