@@ -118,9 +118,9 @@ To assign the hooks call:
118118
119119``` javascript
120120asyncWrap .setupHooks (init, pre, post, destroy);
121- function init (provider , uid , parent ) { /* consumer code */ }
122- function pre () { /* consumer code */ }
123- function post () { /* consumer code */ }
121+ function init (uid , provider , parentUid , parentHandle ) { /* consumer code */ }
122+ function pre (uid ) { /* consumer code */ }
123+ function post (uid ) { /* consumer code */ }
124124function destroy (uid ) { /* consumer code */ }
125125```
126126
@@ -153,21 +153,21 @@ asyncWrap.disable();
153153#### The Hooks
154154
155155Currently there are 4 hooks: ` init ` , ` pre ` , ` post ` ` destroy ` . The ` this `
156- variable refers to the handle object. The ` init ` hook has three extra arguments
157- ` provider ` , ` uid ` and ` parent ` . The ` destroy ` hook also has the ` uid ` argument .
156+ variable refers to the handle object, they all have a ` uid ` argument, finally
157+ ` init ` provides extra information about the creation of the handle object .
158158
159159``` javascript
160- function init (provider , uid , parent ) { }
161- function pre () { }
162- function post () { }
160+ function init (uid , provider , parentUid , parentHandle ) { }
161+ function pre (uid ) { }
162+ function post (uid ) { }
163163function destroy (uid ) { }
164164```
165165
166166##### this
167167
168168In the ` init ` , ` pre ` and ` post ` cases the ` this ` variable is the handle object.
169169Users may read properties from this object such as ` port ` and ` address ` in the
170- ` TCPConnectWrap ` case, or set user specific properties .
170+ ` TCPConnectWrap ` case.
171171
172172In the ` init ` hook the handle object is not yet fully constructed, thus some
173173properties are not safe to read. This causes problems when doing
@@ -211,16 +211,20 @@ At the time of writing this is the current list:
211211
212212##### uid
213213
214- The ` uid ` is a unique integer that identify each handle object. Because the
215- ` destroy ` hook isn't called with the handle object, this is particular useful
216- for storing information related to the handle object, that the user require in
217- the ` destroy ` hook.
214+ The ` uid ` is a unique integer that identifies each handle object. You can use
215+ the ` uid ` to store information related to the handle object, by using it as
216+ a key for a shared ` Map ` object.
218217
219- ##### parent
218+ As such the user could also store information on the ` this ` object, but this
219+ may be unsafe since the user could accidentally overwrite an undocumented
220+ property. The ` this ` object is also not available in the ` destroy ` hook, thus
221+ the ` uid ` is generally the recommended choice.
222+
223+ ##### parentUid
220224
221225In some cases the handle was created from another handle object. In those
222- cases the ` parent ` argument is set the creating handle object. If there is
223- no parent handle then it is just ` null ` .
226+ cases the ` parentUid ` argument is set to the uid of the creating handle object.
227+ If there is no parent then it is just ` null ` .
224228
225229The most common case is the TCP server. The TCP server itself is a ` TCP ` handle,
226230but when receiving new connection it creates another ` TCP ` handle that is
@@ -235,7 +239,11 @@ post // TCP (server)
235239
236240This means it is not possible to know in what handle context the new socket
237241handle was created using the ` pre ` and ` post ` hooks. However the
238- ` parent ` argument provides this information.
242+ ` parentUid ` argument provides this information.
243+
244+ ##### parentHandle
245+
246+ This is similar to parentUid but is the actual parent handle object.
239247
240248## Example
241249
@@ -244,38 +252,47 @@ A classic use case for AsyncWrap is to create a long-stack-trace tool.
244252``` javascript
245253const asyncWrap = process .binding (' async_wrap' );
246254
247- asyncWrap .setupHooks (init, pre, post );
255+ asyncWrap .setupHooks (init, before, after, destroy );
248256asyncWrap .enable ();
249257
250- // global state variable, that contains the current stack trace
251- let currentStack = ' ' ;
258+ // global state variable, that contains the stack traces and the current uid
259+ const stack = new Map ();
260+ stack .set (- 1 , ' ' );
252261
253- function init (provider , uid , parent ) {
262+ let currentUid = - 1 ;
263+
264+ function init (uid , provider , parentUid , parentHandle ) {
254265 // When a handle is created, collect the stack trace such that we later
255266 // can see what involved the handle constructor.
256267 const localStack = (new Error ()).stack .split (' \n ' ).slice (1 ).join (' \n ' );
257268
258- // Compute the full stack and store it as a property on the handle object,
259- // such that it can be fetched later.
260- const extraStack = parent ? parent ._full_init_stack : currentStack;
261- this ._full_init_stack = localStack + ' \n ' + extraStack;
269+ // Compute the full stack and store on the `Map` using the `uid` as key.
270+ const extraStack = stack .get (parentUid || currentUid);
271+ stack .set (uid, localStack + ' \n ' + extraStack);
262272}
263- function pre ( ) {
264- // A callback is about to be called, update the `currentStack ` such that
273+ function before ( uid ) {
274+ // A callback is about to be called, update the `currentUid ` such that
265275 // it is correct for when another handle is initialized or `getStack` is
266276 // called.
267- currentStack = this . _full_init_stack ;
277+ currentUid = uid ;
268278}
269- function post ( ) {
279+ function after ( uid ) {
270280 // At the time of writing there are some odd cases where there is no handle
271281 // context, this line prevents that from resulting in wrong stack trace. But
272282 // the stack trace will be shorter compared to what ideally should happen.
273- currentStack = ' ' ;
283+ currentUid = - 1 ;
284+ }
285+
286+ function destroy (uid ) {
287+ // Once the handle is destroyed no other handle objects can be created with
288+ // this handle as its immediate context. Thus its associated stack can be
289+ // deleted.
290+ stack .delete (uid);
274291}
275292
276293function getStack (message ) {
277294 const localStack = new Error (message);
278- return localStack .stack + ' \n ' + currentStack ;
295+ return localStack .stack + ' \n ' + stack . get (currentUid) ;
279296}
280297module .exports = getStack;
281298```
0 commit comments