GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — async_hooks initial implementation by trevnorris · Pull Request #11883 · nodejs/node

Conversation

@trevnorris

@trevnorris trevnorris commented Mar 16, 2017 •
edited by Fishrock123
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor
Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

async_wrap, async_hooks and a little bit of everything else

This PR supersedes my other PR for async_hooks support. The implementation has been cleaned up and @thlorenz has helped create much better tests (though they may need to be changed from their current location) and which accounts for ~3300 lines of the change. Documentation does exist, but needs to be cleaned up some before it's included. The code is ready for initial review.

For anyone reviewing, I carefully went through and divided all the changes into logical commits that should all pass. So while reviewing feel free to use each commit individually. Though GitHub fails at displaying them in the correct order.

The one aspect of this PR that I don't like but have gone through hell trying to get around to no avail is the usage of initTriggerId(). It's basically a way to propagate the "triggerId" to a constructor. The code comments explain some of those difficulties, but I hope someone can come up with something better.

@nodejs/ctc

Refs: #8531

CI: https://ci.nodejs.org/job/node-test-commit/8503/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fishrock123, AndreasMadsen, rvagg, sveisvei, ORESoftware, devsnek, lucasklaassen, and codenirvana reacted with thumbs up emoji Fishrock123, bnb, AndreasMadsen, rvagg, felixfbecker, matteofigus, sveisvei, aqrln, watilde, ORESoftware, and 3 more reacted with hooray emoji
All reactions
  • 👍 8 reactions
  • 🎉 13 reactions
@nodejs-github-bot nodejs-github-bot added async_hooks Issues and PRs related to the async hooks subsystem. async_wrap build Issues and PRs related to Node.js builds or CI infrastructure. c++ Issues and PRs that require attention from people who are familiar with C++. cares Issues and PRs related to the c-ares dependency or the cares_wrap binding. lib / src Issues and PRs involving general changes in the lib/ or src/ directories. labels Mar 16, 2017
@trevnorris trevnorris added the ctc-review label Mar 16, 2017
@trevnorris
trevnorris force-pushed the async-wrap2 branch from 742ef66 to c235002 Compare March 16, 2017 17:52
@trevnorris trevnorris mentioned this pull request Mar 16, 2017
async_hooks initial implementation #8531
Closed
1 of 7 tasks
@trevnorris
trevnorris force-pushed the async-wrap2 branch from c235002 to 73f0041 Compare March 16, 2017 17:59
@AndreasMadsen

AndreasMadsen commented Mar 16, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Would it make sense to move 556cc9b6d047dd6d3ba95b4390222d11018a52b5 and 922bcec92c72804f24b609133db984a1959eb7ed to a separate PR? These commits appear to be completely separate to async_hooks and since the review process for this PR will be long, it would be nice to get these fixes merged sooner than later.

addaleax reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Trott Trott mentioned this pull request Mar 20, 2017
Node.js Foundation Core Technical Committee (CTC) Meeting 2017-03-22 nodejs/CTC#82
Closed
@addaleax

addaleax commented Mar 20, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Agreed, that makes sense. 556cc9b6d047dd6d3ba95b4390222d11018a52b5 is actually exactly the alternative to #11776 that I had in mind (#11776 (comment)).

edit: to be clear, I would still prefer the way 556cc9b6d047dd6d3ba95b4390222d11018a52b5 does it

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

addaleax
addaleax reviewed Mar 20, 2017
View reviewed changes
Comment thread src/node_zlib.cc Outdated

@addaleax addaleax Mar 20, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to keep this equal to the class names, sure, but I would consider ZLIB the more obvious/readable choice (so renaming the class might actually be better?).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 21, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can live with that. Will change.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/udp_wrap.cc Outdated

@addaleax addaleax Mar 20, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ditto, UDPSENDWRAP > SENDWRAP imho)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 21, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what I was thinking here. will change.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Fishrock123
Fishrock123 reviewed Mar 20, 2017
View reviewed changes

@Fishrock123 Fishrock123 left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same timers comments as the previous PR?

Maybe check the old PR and check the code locations for timers.js there?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/timers.js Outdated

@Fishrock123 Fishrock123 Mar 20, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is in the wrong spot again?

Shouldn't it be in unenroll and Timeout#close()?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 21, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is intentional. The previous implementation was fragile, so I decided it would be better to harden by restricting the scope to only timers created with setImmediate/setTimeout/setInterval. I'd prefer to add a test that shows how not having these calls in unenroll and Timeout#close causes the async graph to be incorrect before attempting to change their locations.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Mar 21, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this miss net timeouts then?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 21, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic would lead me to believe so, but I don't have a test to verify that yet

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Apr 4, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok well, the tests seem to ignore timeouts in the net tests so it was never caught. Run any net server connection and you will quickly find that destroy is never reported on timers for any connection that does not timeout.

Correction, you will see TIMERWRAP but not individual timers.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/timers.js Outdated

@Fishrock123 Fishrock123 Mar 20, 2017 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still needs to go into insert(), I'm quite certain.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@trevnorris

trevnorris commented Mar 20, 2017

Copy link
Copy Markdown
Contributor Author

@addaleax I've split out that one commit: #11947

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@trevnorris
trevnorris force-pushed the async-wrap2 branch from 73f0041 to 435dee8 Compare March 20, 2017 23:42
@rvagg

rvagg commented Mar 22, 2017

Copy link
Copy Markdown
Member

@trevnorris CI failures on all Windows versions for parallel/test-async-wrap-getasyncid, e.g. on this one

not ok 2 parallel/test-async-wrap-getasyncid
  ---
  duration_ms: 0.186
  severity: fail
  stack: |-
    (node:6548) [DEP0064] DeprecationWarning: tls.createSecurePair() is deprecated. Please use tls.Socket instead.
    c:\workspace\node-test-binary-windows\RUN_SUBSET\2\VS_VERSION\vs2015\label\win2016\test\parallel\test-async-wrap-getasyncid.js:176
          throw new Error(`write failed: ${process.binding('uv').errname(err)}`);
          ^
    
    Error: write failed: EPIPE
        at TCPConnectWrap.req.oncomplete.common.mustCall (c:\workspace\node-test-binary-windows\RUN_SUBSET\2\VS_VERSION\vs2015\label\win2016\test\parallel\test-async-wrap-getasyncid.js:176:13)
        at TCPConnectWrap.oncomplete (c:\workspace\node-test-binary-windows\RUN_SUBSET\2\VS_VERSION\vs2015\label\win2016\test\common.js:517:15)

Also, I can't run another CI because this needs rebasing already https://ci.nodejs.org/job/node-test-commit/8612/console

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AndreasMadsen AndreasMadsen mentioned this pull request Mar 22, 2017
Missing stack traces from async functions after the first await #11865
Closed
@trevnorris
trevnorris force-pushed the async-wrap2 branch from 435dee8 to 9f4c893 Compare March 23, 2017 22:20
@Fishrock123

Fishrock123 commented Mar 24, 2017

Copy link
Copy Markdown
Contributor

Updated CI: https://ci.nodejs.org/job/node-test-pull-request/7022/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AndreasMadsen AndreasMadsen mentioned this pull request Mar 26, 2017
async_wrap,lib: Firing async-wrap callbacks for next-tick callbacks #6082
Closed
3 of 4 tasks
@Trott Trott mentioned this pull request Mar 26, 2017
Node.js Foundation Core Technical Committee (CTC) Meeting 2017-03-29 nodejs/CTC#85
Closed
@AndreasMadsen AndreasMadsen mentioned this pull request Mar 27, 2017
[async_hooks] tracking issue nodejs/diagnostics#29
Closed
23 of 27 tasks
@trevnorris
trevnorris force-pushed the async-wrap2 branch 2 times, most recently from b39e7b1 to 8a962d2 Compare March 27, 2017 23:24
addaleax
addaleax reviewed Mar 27, 2017
View reviewed changes
Comment thread lib/_http_agent.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the _asyncId properties use a Symbol instead, if only because that increases readability?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 28, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/_http_agent.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure I understand this, this call is here to tell the subsequent process.nextTick who is responsible for the call?

Have you tried making an internal version of process.nextTick() that takes an async ID? That seems like a more direct approach…

Even it that’s not feasible (for now), a shorthand for setInitTriggerId() + process.nextTick() would be helpful for readability.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fishrock123 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@trevnorris trevnorris Mar 28, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generalized the call b/c of the not-so-obvious way that constructors like TCPConnectWrap() works. setInitTriggerId() is a little devil child that I'd love to banish to the depths of hell, but every time I've attempted to remove it there are complications.

Anyhow, I had considered creating an internal nextTick() that accepts the triggerId but didn't know how people would feel about it. I'll be happy to add it in if others are okay with it being introduced.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/async_hooks.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in the comment: counts

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/async_hooks.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just if (e.stack)? If you want to filter for native errors only, you could also make process.binding('util').isNativeError available

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 28, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yup, good call.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 31, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about if (typeof e.stack === 'string')?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/async_hooks.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably just use constructor({ init, before, after, destroy }) if you want

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/net.js Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment supposed to stay?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/async-wrap.cc Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can you leave a space above this so that it’s more obvious where the macro ends?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/async-wrap.cc Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shares quite a bit of code with AddIdToDestroyList, any chance those could be joined into a common helper?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/env-inl.h Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

“bootstrap” as in “bootstrap_node.js”?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Mar 28, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all sync work at startup will have that id, afaik

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 31, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bootstrap meaning all the code that runs before the first uv_run() is executed.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@Fishrock123 Fishrock123 Mar 31, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should specify that?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Apr 3, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/async-wrap.h Outdated

@addaleax addaleax Mar 27, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do callbacks from native addons fit into this?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trevnorris trevnorris Mar 28, 2017

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AsyncWrap uses an enum so it can store and more easily access the char* of each provider's name for provider_type(), and a couple other things. There will be a native API for async hooks, but I'm not including that in this PR. After this lands I'll post the native API PR.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@AndreasMadsen

AndreasMadsen commented Mar 28, 2017

Copy link
Copy Markdown
Member

V8 5.7 (#11752) has landed with PromiseHooks. See design document: https://docs.google.com/document/d/1rda3yKGHimKIhg5YeoAmCOtyURgsbTH_qaYR79FELlk/edit?usp=sharing

sveisvei reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Trott Trott mentioned this pull request Apr 3, 2017
Node.js Foundation Core Technical Committee (CTC) Meeting 2017-04-05 nodejs/CTC#93
Closed
@addaleax addaleax mentioned this pull request Apr 3, 2017
Refactor/code optimization #12187
Closed
4 tasks
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
async_wrap: use double, not int64_t, for async id
0432c6e
The number of ids is limited to 2^53-1 regardless of whether an int64_t
is used or not because JS is limited to a double. So to make conversion
simpler, track ids internally as a double. This will also make life
simpler when this is eventually exposed to JS via a Float64Array.

Rename AsyncWrap::get_uid() to AsyncWrap::get_id().

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
crypto: use named FunctionTemplate
d9f3ec8
RandomBytes and PBKDF2 were using the same "generic" ObjectTemplate for
construction. Instead create one for each that is properly named.

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
async_wrap: use more specific providers
f1ed19d
Instead of wrapping several providers into PROVIDER_CRYPTO, have them
all be named after their class. Rename other providers to also match
their class names. With the exception of Parser. Which is actually
HTTPParser.

Add PROVIDER_LENGTH to make better checks in WrapperInfo().

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
async_wrap,src: add GetAsyncId() method
fe2df3b
Allow handles to retrieve their own uid's by adding a new method on the
FunctionTemplates. Implementation of these into all other classes will
come in a future commit.

Add the method AsyncWrap::GetAsyncId() to all inheriting class objects
so the uid of the handle can be retrieved from JS.

In all applicable locations, run ClearWrap() on the object holding the
pointer so that it never points to invalid memory and make sure Wrap()
is always run so the class pointer is correctly attached to the object
and can be retrieved so GetAsyncId() can be run.

In many places a class instance was not removing its own pointer from
object() in the destructor. This left an invalid pointer in the JS
object that could cause the application to segfault under certain
conditions.

Remove ClearWrap() from ReqWrap for continuity. The ReqWrap constructor
was not the one to call Wrap(), so it shouldn't be the one to call
ClearWrap().

Wrap() has been added to all constructors that inherit from AsyncWrap.
Normally it's the child most class. Except in the case of HandleWrap.
Which must be the constructor that runs Wrap() because the class pointer
is retrieved for certain calls and because other child classes have
multiple inheritance to pointer to the HandleWrap needs to be stored.

ClearWrap() has been placed in all FunctionTemplate constructors so that
no random values are returned when running getAsyncId(). ClearWrap() has
also been placed in all class destructors, except in those that use
MakeWeak() because the destructor will run during GC. Making the
object() inaccessible.

It could be simplified to where AsyncWrap sets the internal pointer,
then if an inheriting class needs one of it's own it could set it again.
But the inverse would need to be true also, where AsyncWrap then also
runs ClearWeak. Unforunately because some of the handles are cleaned up
during GC that's impossible. Also in the case of ReqWrap it runs Reset()
in the destructor, making the object() inaccessible. Meaning,
ClearWrap() must be run by the class that runs Wrap(). There's currently
no generalized way of taking care of this across all instances of
AsyncWrap.

I'd prefer that there be checks in there for these things, but haven't
found a way to place them that wouldn't be just as unreliable.

Add test that checks all resources that can run getAsyncId(). Would like
a way to enforce that any new classes that can also run getAsyncId() are
tested, but don't have one.

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
src: implement native changes for async_hooks
c0bde73
Changes in the native code for the upcoming async_hooks module. These
have been separated to help with review and testing.

Changes include:

* Introduce an async id stack that tracks recursive calls into async
  execution contexts. For performance reasons the id stack is held as a
  double* and assigned to a Float64Array. If the stack grows too large
  it is then placed in it's own stack and replaced with a new double*.
  This should accommodate arbitrarily large stacks.

  I'm not especially happy with the complexity involved with this async
  id stack, but it's also the fastest and most full proof way of
  handling it that I have found.

* Add helper functions in Environment and AsyncWrap to work with the
  async id stack.

* Add AsyncWrap::Reset() to allow AsyncWrap instances that have been
  placed in a resource pool, instead of being released, to be
  reinitialized. AsyncWrap::AsyncWrap() also now uses Reset() for
  initialization.

* AsyncWrap* parent no longer needs to be passed via the constructor.

* Introduce Environment::AsyncHooks class to contain the needed native
  functionality. This includes the pointer to the async id stack, and
  array of v8::Eternal<v8::String>'s that hold the names of all
  providers, mechanisms for storing/retrieving the trigger id, etc.

* Introduce Environment::AsyncHooks::ExecScope as a way to track the
  current id and trigger id of function execution via RAII.

* If the user passes --abort-on-uncaught-exception then instead of
  throwing the application will print a stack trace and abort.

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
async_hooks: initial async_hooks implementation
7e3a3c9
Fill this commit messsage with more details about the change once all
changes are rebased.

* Add lib/async_hooks.js

* Add JS methods to AsyncWrap for handling the async id stack

* Introduce AsyncReset() so that JS functions can reset the id and again
  trigger the init hooks, allow AsyncWrap::Reset() to be called from JS
  via asyncReset().

* Add env variable to test additional things in test/common.js

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
lib: implement async_hooks API in core
4a7233c
Implement async_hooks support in the following:

* fatalException handler
* process.nextTick
* Timers
* net/dgram/http

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@thlorenz @addaleax
test: adding tests for initHooks API
e3e56f1
Async wrap providers tested:

- crypto.randomBytes
- crypto.pbkdf2
- fs event wrap
- fsreqwrap access
- fsreqwrap readFile
- getaddrinforeq wrap
- getnameinforeq wrap
- pipe connect wrap
- query wrap
- pipewrap
- processwrap
- shutdown wrap
- tcpwrap
- udpwrap
- send wrap
- detailed signal wrap
- statwatcher
- timerwrap via setTimeout
- timerwrap via setInterval
- for Immediate
- http parser request
- http parser response
- connection via ssl server
- tls wrap
- write wrap
- ttywrap via readstream
- ttywrap via wriream
- zctx via zlib binding deflate

Embedder API:

-  async-event tests
  - one test looks at the happy paths
  - another ensures that in cases of events emitted in an order that
  doesn't make sense, the order is enforced by async hooks throwing a
  meaningful error
  - embedder enforcement tests are split up since async hook stack
  corruption now the process
  - therefore we launch a child and check for error output of the offending code

Additional tests:

- tests that show that we can enable/disable hooks inside their lifetime
events
- tests that verify the graph of resources triggering the creation of
other resources

Test Helpers:

- init-hooks:
  - returns one collector instance
  - when created an async hook is created and the lifetime events are
  registered to call the appropriate collector functions
  - the collector also exposes `enable` and `disable` functions which call
  through to the async hook

- hook checks:
  - checks invocations of life time hooks against the actual invocations
  that were collected
  - in some cases like `destroy` a min/max range of invocations can be
  supplied since in these cases the exact number is non-deterministic

- verify graph:
  - verifies the triggerIds of specific async resources are as expected,
  i.e. the creation of resources was triggered by the resource we expect
  - includes a printGraph function to generate easily readable test
  input for verify graph
  - both functions prune TickObjects to create less brittle and easier
  to understand tests

PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
addaleax pushed a commit that referenced this pull request May 10, 2017
@trevnorris @addaleax
makefile: add async-hooks to test and test-ci
c68ebe8
PR-URL: #12892
Ref: #11883
Ref: #8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
@addaleax

addaleax commented May 10, 2017

Copy link
Copy Markdown
Member

Landed as #12892 in dd6e3f6...c68ebe8

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@addaleax addaleax closed this May 10, 2017
@AndreasMadsen AndreasMadsen mentioned this pull request May 11, 2017
docs: documenting async hooks features #12953
Closed
1 of 2 tasks
@trevnorris

trevnorris commented May 15, 2017

Copy link
Copy Markdown
Contributor Author

@AndreasMadsen I only just saw your latest list of comments. I'll get working on those.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
tty_wrap: throw when uv_tty_init() returns error
c6f7c8e
Also add checks in lib/tty.js and tests.

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
test: remove unneeded tests
b0602ef
AsyncWrap will be going through many changes, and the old API will no
longer be used. So remove those tests that will no longer be useful.
They may be added back later using the new API, once fully implemented.

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
async_wrap: use double, not int64_t, for async id
49ddd77
The number of ids is limited to 2^53-1 regardless of whether an int64_t
is used or not because JS is limited to a double. So to make conversion
simpler, track ids internally as a double. This will also make life
simpler when this is eventually exposed to JS via a Float64Array.

Rename AsyncWrap::get_uid() to AsyncWrap::get_id().

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
crypto: use named FunctionTemplate
e59c4bb
RandomBytes and PBKDF2 were using the same "generic" ObjectTemplate for
construction. Instead create one for each that is properly named.

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
async_wrap: use more specific providers
3e183dc
Instead of wrapping several providers into PROVIDER_CRYPTO, have them
all be named after their class. Rename other providers to also match
their class names. With the exception of Parser. Which is actually
HTTPParser.

Add PROVIDER_LENGTH to make better checks in WrapperInfo().

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
async_wrap,src: add GetAsyncId() method
8130199
Allow handles to retrieve their own uid's by adding a new method on the
FunctionTemplates. Implementation of these into all other classes will
come in a future commit.

Add the method AsyncWrap::GetAsyncId() to all inheriting class objects
so the uid of the handle can be retrieved from JS.

In all applicable locations, run ClearWrap() on the object holding the
pointer so that it never points to invalid memory and make sure Wrap()
is always run so the class pointer is correctly attached to the object
and can be retrieved so GetAsyncId() can be run.

In many places a class instance was not removing its own pointer from
object() in the destructor. This left an invalid pointer in the JS
object that could cause the application to segfault under certain
conditions.

Remove ClearWrap() from ReqWrap for continuity. The ReqWrap constructor
was not the one to call Wrap(), so it shouldn't be the one to call
ClearWrap().

Wrap() has been added to all constructors that inherit from AsyncWrap.
Normally it's the child most class. Except in the case of HandleWrap.
Which must be the constructor that runs Wrap() because the class pointer
is retrieved for certain calls and because other child classes have
multiple inheritance to pointer to the HandleWrap needs to be stored.

ClearWrap() has been placed in all FunctionTemplate constructors so that
no random values are returned when running getAsyncId(). ClearWrap() has
also been placed in all class destructors, except in those that use
MakeWeak() because the destructor will run during GC. Making the
object() inaccessible.

It could be simplified to where AsyncWrap sets the internal pointer,
then if an inheriting class needs one of it's own it could set it again.
But the inverse would need to be true also, where AsyncWrap then also
runs ClearWeak. Unforunately because some of the handles are cleaned up
during GC that's impossible. Also in the case of ReqWrap it runs Reset()
in the destructor, making the object() inaccessible. Meaning,
ClearWrap() must be run by the class that runs Wrap(). There's currently
no generalized way of taking care of this across all instances of
AsyncWrap.

I'd prefer that there be checks in there for these things, but haven't
found a way to place them that wouldn't be just as unreliable.

Add test that checks all resources that can run getAsyncId(). Would like
a way to enforce that any new classes that can also run getAsyncId() are
tested, but don't have one.

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
src: implement native changes for async_hooks
d644fda
Changes in the native code for the upcoming async_hooks module. These
have been separated to help with review and testing.

Changes include:

* Introduce an async id stack that tracks recursive calls into async
  execution contexts. For performance reasons the id stack is held as a
  double* and assigned to a Float64Array. If the stack grows too large
  it is then placed in it's own stack and replaced with a new double*.
  This should accommodate arbitrarily large stacks.

  I'm not especially happy with the complexity involved with this async
  id stack, but it's also the fastest and most full proof way of
  handling it that I have found.

* Add helper functions in Environment and AsyncWrap to work with the
  async id stack.

* Add AsyncWrap::Reset() to allow AsyncWrap instances that have been
  placed in a resource pool, instead of being released, to be
  reinitialized. AsyncWrap::AsyncWrap() also now uses Reset() for
  initialization.

* AsyncWrap* parent no longer needs to be passed via the constructor.

* Introduce Environment::AsyncHooks class to contain the needed native
  functionality. This includes the pointer to the async id stack, and
  array of v8::Eternal<v8::String>'s that hold the names of all
  providers, mechanisms for storing/retrieving the trigger id, etc.

* Introduce Environment::AsyncHooks::ExecScope as a way to track the
  current id and trigger id of function execution via RAII.

* If the user passes --abort-on-uncaught-exception then instead of
  throwing the application will print a stack trace and abort.

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
async_hooks: initial async_hooks implementation
959eb7e
Fill this commit messsage with more details about the change once all
changes are rebased.

* Add lib/async_hooks.js

* Add JS methods to AsyncWrap for handling the async id stack

* Introduce AsyncReset() so that JS functions can reset the id and again
  trigger the init hooks, allow AsyncWrap::Reset() to be called from JS
  via asyncReset().

* Add env variable to test additional things in test/common.js

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
lib: implement async_hooks API in core
5695596
Implement async_hooks support in the following:

* fatalException handler
* process.nextTick
* Timers
* net/dgram/http

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@thlorenz Olivier Martin
test: adding tests for initHooks API
e9aa9a9
Async wrap providers tested:

- crypto.randomBytes
- crypto.pbkdf2
- fs event wrap
- fsreqwrap access
- fsreqwrap readFile
- getaddrinforeq wrap
- getnameinforeq wrap
- pipe connect wrap
- query wrap
- pipewrap
- processwrap
- shutdown wrap
- tcpwrap
- udpwrap
- send wrap
- detailed signal wrap
- statwatcher
- timerwrap via setTimeout
- timerwrap via setInterval
- for Immediate
- http parser request
- http parser response
- connection via ssl server
- tls wrap
- write wrap
- ttywrap via readstream
- ttywrap via wriream
- zctx via zlib binding deflate

Embedder API:

-  async-event tests
  - one test looks at the happy paths
  - another ensures that in cases of events emitted in an order that
  doesn't make sense, the order is enforced by async hooks throwing a
  meaningful error
  - embedder enforcement tests are split up since async hook stack
  corruption now the process
  - therefore we launch a child and check for error output of the offending code

Additional tests:

- tests that show that we can enable/disable hooks inside their lifetime
events
- tests that verify the graph of resources triggering the creation of
other resources

Test Helpers:

- init-hooks:
  - returns one collector instance
  - when created an async hook is created and the lifetime events are
  registered to call the appropriate collector functions
  - the collector also exposes `enable` and `disable` functions which call
  through to the async hook

- hook checks:
  - checks invocations of life time hooks against the actual invocations
  that were collected
  - in some cases like `destroy` a min/max range of invocations can be
  supplied since in these cases the exact number is non-deterministic

- verify graph:
  - verifies the triggerIds of specific async resources are as expected,
  i.e. the creation of resources was triggered by the resource we expect
  - includes a printGraph function to generate easily readable test
  input for verify graph
  - both functions prune TickObjects to create less brittle and easier
  to understand tests

PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
@trevnorris Olivier Martin
makefile: add async-hooks to test and test-ci
7131fa6
PR-URL: nodejs#12892
Ref: nodejs#11883
Ref: nodejs#8531
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Sam Roberts <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Jeremiah Senkpiel <[email protected]>
@JiaLiPassion JiaLiPassion mentioned this pull request May 21, 2017
Questions: will nodejs expose SetPromiseHook of V8 as javascript API in the future? #13139
Closed
@AndreasMadsen AndreasMadsen mentioned this pull request Jun 1, 2017
async_hooks: use parent promise as triggerId in init hook #13367
Closed
3 of 4 tasks
@AndreasMadsen AndreasMadsen mentioned this pull request Jul 17, 2017
Remove async_hooks runInAsyncIdScope API #14328
Closed
@AndreasMadsen AndreasMadsen added the dont-land-on-v6.x label Jul 18, 2017
@refack refack mentioned this pull request Aug 12, 2017
RFC: seeking feedback on async_hooks performance in production #14794
Closed
@Linkgoron Linkgoron mentioned this pull request Apr 4, 2021
async_hooks: fatalError(e) function checking error Object #38077
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@addaleax addaleax addaleax left review comments
+2 more reviewers
@Fishrock123 Fishrock123 Fishrock123 left review comments
@AndreasMadsen AndreasMadsen AndreasMadsen requested changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

async_hooks Issues and PRs related to the async hooks subsystem. build Issues and PRs related to Node.js builds or CI infrastructure. c++ Issues and PRs that require attention from people who are familiar with C++. cares Issues and PRs related to the c-ares dependency or the cares_wrap binding. lib / src Issues and PRs involving general changes in the lib/ or src/ directories. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

10 participants

@trevnorris @AndreasMadsen @addaleax @rvagg @Fishrock123 @jasnell @thlorenz @refack @sam-github @nodejs-github-bot
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.