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

async_hooks: minor refactor to callback invocation #13419

Closed

Conversation

addaleax
Copy link
Member

@addaleax addaleax commented Jun 2, 2017

Re-use the init function wherever possible, and move
try { … } catch blocks that result in fatal errors to a larger
scope.

Also make the argument order for init() consistent in the codebase.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

async_hooks /cc @nodejs/async_hooks

@nodejs-github-bot nodejs-github-bot added async_hooks Issues and PRs related to the async hooks subsystem. async_wrap c++ Issues and PRs that require attention from people who are familiar with C++. labels Jun 2, 2017
Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

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

Very nice

if (typeof active_hooks_array[i][before_symbol] === 'function') {
runCallback(active_hooks_array[i][before_symbol], asyncId);
try {
for (var i = 0; i < active_hooks_array.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not for ... of?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don’t know, but I wouldn’t be surprised if this variant would continue to be faster (i.e. I’m reluctant to change this without benchmarking – if you do and you get good results, sure).

Copy link
Contributor

Choose a reason for hiding this comment

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

ack

Copy link
Contributor

Choose a reason for hiding this comment

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

The original reason for this was that the array index was used. This was before the design decision to not allow the callable hooks to be altered during execution of all hooks; not for benchmarking reasons. Though I'd say no sense in changing it unless benchmarks show there is an improvement.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ack.
Was curious so I just tested and FOI (For Our Information):

> var a = [1]
undefined
> for (let b of a) { b === 1 && a.push(2); console.log(b)}
1
2

Copy link
Contributor

Choose a reason for hiding this comment

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

@refack That's no longer an issue, which is why the index is no longer used. At the top of the file you'll see:

// Use to temporarily store and updated active_hooks_array if the user enables
// or disables a hook while hooks are being processed.
var tmp_active_hooks_array = null;
// Keep track of the field counts held in tmp_active_hooks_array.
var tmp_async_hook_fields = null;

Which getHooksArray() automatically assigns the old array to and duplicates the new altered array. So it's impossible for the user to alter the hooks mid-execution. i.e. you'll never see the case of "a.push()" to the actual array that contains the hooks in the middle of execution. So feel free to benchmark it all you want.

emitBeforeN(asyncId);
}


// Called from native. The asyncId stack handling is taken care of there before
// this is called.
function emitAfterN(asyncId) {
if (async_hook_fields[kAfter] > 0) {
processing_hook = true;
processing_hook = true;
Copy link
Member

Choose a reason for hiding this comment

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

Why was the if (async_hook_fields[kAfter] > 0) short circuit removed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I’ve added it to emitAfterS now; The idea is that the native code doesn’t bother calling emitAfterN if the field is 0, so checking it here is pointless for the common case of a call from C++.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note for future change: I'd like to include a macros.py similar to deps/v8/src/js/macros.py for Debug builds. except it replaces comments instead of normal expressions.

In the code you'll find // CHECK() comments that were meant as reminders of important bits to check, but not important enough to check in a Release build. Though the difference would be that

// CHECK(expr)

is replaced with something like

assert.ok(expr);

But only for debug builds.

Point here would be to include the following here:

// CHECK(async_hook_fields[kAfter] > 0)

as a sanity check for the future in case a change is made that invalidates your comment of

The idea is that the native code doesn’t bother calling emitAfterN if the field is 0, so checking it here is pointless for the common case of a call from C++.

@@ -412,11 +397,17 @@ function emitDestroyS(asyncId) {


function emitDestroyN(asyncId) {
if (async_hook_fields[kDestroy] === 0) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, this is superfluous, thanks for pointing out.

@addaleax addaleax force-pushed the async-hooks-callback-calling-refactor branch from b347faa to 91a6e96 Compare June 3, 2017 09:43
@addaleax
Copy link
Member Author

addaleax commented Jun 3, 2017

@refack @AndreasMadsen Thanks for pointing these out, this is updated now

Copy link
Member

@AndreasMadsen AndreasMadsen left a comment

Choose a reason for hiding this comment

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

LGTM

@trevnorris
Copy link
Contributor

@addaleax Mind adding a comment either in the code or commit message body about why moving the try/catch outside the for loop is an improvement? I have no issue w/ it. Just for posterity.

Copy link
Contributor

@trevnorris trevnorris left a comment

Choose a reason for hiding this comment

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

Left a comment about leaving a more detailed comment, but not a blocker. LGTM

Re-use the `init` function wherever possible, and move
`try { … } catch` blocks that result in fatal errors to a larger
scope.

Also make the argument order for `init()` consistent in the codebase.
@addaleax addaleax force-pushed the async-hooks-callback-calling-refactor branch from 91a6e96 to 868abac Compare June 7, 2017 19:15
@addaleax
Copy link
Member Author

addaleax commented Jun 7, 2017

Rebased and added a comment about the try/catchs.

@addaleax
Copy link
Member Author

addaleax commented Jun 7, 2017

@addaleax
Copy link
Member Author

addaleax commented Jun 8, 2017

Landed in 02aea06

@addaleax addaleax closed this Jun 8, 2017
@addaleax addaleax deleted the async-hooks-callback-calling-refactor branch June 8, 2017 21:59
sam-github pushed a commit to sam-github/node that referenced this pull request Jun 8, 2017
Re-use the `init` function wherever possible, and move
`try { … } catch` blocks that result in fatal errors to a larger
scope.

Also make the argument order for `init()` consistent in the codebase.

PR-URL: nodejs#13419
Reviewed-By: Trevor Norris <[email protected]>
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
addaleax added a commit that referenced this pull request Jun 10, 2017
Re-use the `init` function wherever possible, and move
`try { … } catch` blocks that result in fatal errors to a larger
scope.

Also make the argument order for `init()` consistent in the codebase.

PR-URL: #13419
Reviewed-By: Trevor Norris <[email protected]>
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Refael Ackermann <[email protected]>
@addaleax addaleax mentioned this pull request Jun 10, 2017
@gibfahn gibfahn mentioned this pull request Jun 15, 2017
3 tasks
@refack refack mentioned this pull request Jul 9, 2017
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
async_hooks Issues and PRs related to the async hooks subsystem. c++ Issues and PRs that require attention from people who are familiar with C++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants