-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
async_hooks initial implementation #11883
Commits on Apr 12, 2017
-
tty_wrap: throw when uv_tty_init() returns error
Also add checks in lib/tty.js and tests.
Configuration menu - View commit details
-
Copy full SHA for 2bbbeb6 - Browse repository at this point
Copy the full SHA 2bbbeb6View commit details -
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.
Configuration menu - View commit details
-
Copy full SHA for a5504e5 - Browse repository at this point
Copy the full SHA a5504e5View commit details -
async_wrap: use double, not int64_t, for async id
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().
Configuration menu - View commit details
-
Copy full SHA for 484ecfd - Browse repository at this point
Copy the full SHA 484ecfdView commit details -
crypto: use named FunctionTemplate
RandomBytes and PBKDF2 were using the same "generic" ObjectTemplate for construction. Instead create one for each that is properly named.
Configuration menu - View commit details
-
Copy full SHA for 6d024ce - Browse repository at this point
Copy the full SHA 6d024ceView commit details -
async_wrap: use more specific providers
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().
Configuration menu - View commit details
-
Copy full SHA for f090fd2 - Browse repository at this point
Copy the full SHA f090fd2View commit details -
async_wrap,src: add GetAsyncId() method
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.
Configuration menu - View commit details
-
Copy full SHA for 6d11989 - Browse repository at this point
Copy the full SHA 6d11989View commit details -
src: implement native changes for async_hooks
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.
Configuration menu - View commit details
-
Copy full SHA for a556aca - Browse repository at this point
Copy the full SHA a556acaView commit details -
async_hooks: initial async_hooks implementation
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
Configuration menu - View commit details
-
Copy full SHA for 0228da6 - Browse repository at this point
Copy the full SHA 0228da6View commit details -
lib: implement aysnc_hooks API in core
Implement async_hooks support in the following: * fatalException handler * process.nextTick * Timers * net/dgram/http
Configuration menu - View commit details
-
Copy full SHA for 3783c98 - Browse repository at this point
Copy the full SHA 3783c98View commit details -
async-hooks: adding tests for initHooks API
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
Configuration menu - View commit details
-
Copy full SHA for 09b78e0 - Browse repository at this point
Copy the full SHA 09b78e0View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3bca39d - Browse repository at this point
Copy the full SHA 3bca39dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 75f2d2a - Browse repository at this point
Copy the full SHA 75f2d2aView commit details