Skip to content
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

Use async_hooks for Node.js 8.2.0 and above #77

Merged
merged 7 commits into from
Jan 2, 2018

Conversation

watson
Copy link
Contributor

@watson watson commented Nov 24, 2017

Todo:

  • Investigate if it's worth it filtering out TIMERWRAP - See Use async_hooks for Node.js 8.2.0 and above #77 (comment)
  • Investigate if we should add a hook for promiseResolve as well
  • Benchmark the difference in overhead between this solution and the monkey-patching solution in use pre-v8.2.0

@watson watson force-pushed the asynchooks branch 4 times, most recently from 16572d5 to 75a6d05 Compare November 24, 2017 15:16
}
}
function before (asyncId) {
if (!initState.has(asyncId)) return // in case type === TIMERWRAP
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to consider if the benefit of filtering out TIMERWRAP types outweigh the overhead of these has() calls

@watson watson force-pushed the asynchooks branch 4 times, most recently from 6ee9f1c to b55231e Compare November 27, 2017 13:26
@watson
Copy link
Contributor Author

watson commented Nov 29, 2017

Concern: We'd probably lose context if using AsyncHooks if a call goes through a native module that isn't using n-api. There's work going on to get AsyncHooks to work with Nan in the Node.js Diagnostic WG, but it's far from ready.

@watson
Copy link
Contributor Author

watson commented Dec 13, 2017

@Qard I just took a look at WeakMap and as far as I can see we can't use it as the weak part is the key and not the value, and so the key needs to be an object (asyncId is a number):

The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced. The keys must be objects and the values can be arbitrary values.

@Qard
Copy link
Contributor

Qard commented Dec 13, 2017

Ah, right...maybe we can just do some testing around the clear* functions to make sure the references are getting cleared from the maps properly?

@watson
Copy link
Contributor Author

watson commented Dec 13, 2017

Concern: We'd probably lose context if using AsyncHooks if a call goes through a native module that isn't using n-api. There's work going on to get AsyncHooks to work with Nan in the Node.js Diagnostic WG, but it's far from ready.

On second thought, this really doesn't matter as it's the same issue with our monkey patched version of the code.

@watson watson force-pushed the asynchooks branch 4 times, most recently from 13fb8c8 to 917b181 Compare December 13, 2017 20:03
@codecov-io
Copy link

codecov-io commented Dec 13, 2017

Codecov Report

Merging #77 into master will decrease coverage by 1.96%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #77      +/-   ##
==========================================
- Coverage   82.51%   80.55%   -1.97%     
==========================================
  Files          38       39       +1     
  Lines        1922     1939      +17     
==========================================
- Hits         1586     1562      -24     
- Misses        336      377      +41
Impacted Files Coverage Δ
lib/config.js 95.55% <ø> (ø) ⬆️
lib/instrumentation/index.js 90.9% <100%> (+0.36%) ⬆️
lib/instrumentation/async-hooks.js 100% <100%> (ø)
lib/instrumentation/es6-wrapped-promise.js 14.28% <0%> (-78.58%) ⬇️
lib/instrumentation/patch-async.js 48.98% <0%> (-12.15%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eee12ef...6a384ff. Read the comment docs.

}

function destroy (asyncId) {
if (!transactions.has(asyncId)) return // in case type === TIMERWRAP
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I imagine leaving this up to the Map.prototype.delete function is just as efficient

Copy link
Contributor

@Qard Qard Dec 21, 2017

Choose a reason for hiding this comment

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

Same as get, this may deopt if it tries to delete an item that doesn't exist.

Object.defineProperty(ins, 'currentTransaction', {
get: function () {
const asyncId = asyncHooks.executionAsyncId()
return transactions.get(asyncId)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if it's still the case, but previously map.get(...) could deopt if the item did not exist. It might be a good idea to put a if (!transactions.has(asyncId)) return before the get.

}

function destroy (asyncId) {
if (!transactions.has(asyncId)) return // in case type === TIMERWRAP
Copy link
Contributor

@Qard Qard Dec 21, 2017

Choose a reason for hiding this comment

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

Same as get, this may deopt if it tries to delete an item that doesn't exist.

@Qard
Copy link
Contributor

Qard commented Dec 21, 2017

Looks like async_hooks.executionAsyncId() was actually not added until 8.2.

@watson
Copy link
Contributor Author

watson commented Dec 22, 2017

@Qard Ah good catch regarding v8.2. I'll update the version requirement 😃

@watson watson changed the title Use async_hooks for Node.js 8.1.0 and above Use async_hooks for Node.js 8.2.0 and above Dec 23, 2017
@watson
Copy link
Contributor Author

watson commented Dec 23, 2017

Here's how the new Compatibility top section looks:

image

And here's how the new section in the Agent API docs looks:

image

@watson
Copy link
Contributor Author

watson commented Dec 23, 2017

@Qard I think this is ready now. If you're ok with it I'll merge it into master and release a new version to npm

@watson watson removed the in progress label Jan 2, 2018
@watson watson merged commit ab5d6cd into elastic:master Jan 2, 2018
@watson watson deleted the asynchooks branch January 2, 2018 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants