async_hooks: reduce code duplication by using a factory#13755
async_hooks: reduce code duplication by using a factory#13755BridgeAR wants to merge 7 commits intonodejs:masterfrom
Conversation
lib/async_hooks.js
Outdated
There was a problem hiding this comment.
Why is this still called emitAfterN?
lib/async_hooks.js
Outdated
There was a problem hiding this comment.
This line is over 80 characters.
trevnorris
left a comment
There was a problem hiding this comment.
Minor change request, but other than that LGTM
lib/async_hooks.js
Outdated
| const before_symbol = Symbol('before'); | ||
| const after_symbol = Symbol('after'); | ||
| const destroy_symbol = Symbol('destroy'); | ||
| const emitBeforeN = hookFactory(before_symbol); |
There was a problem hiding this comment.
nit: change this to hookFactoryEmit or emitHookFactory.
|
|
||
| // I'd prefer allowing these checks to not exist, or only throw in a debug | ||
| // build, in order to improve performance. | ||
| // TODO(trevnorris): I'd prefer allowing these checks to not exist, or only |
There was a problem hiding this comment.
good call changing this to a TODO.
lib/async_hooks.js
Outdated
| function hookFactory(symbol) { | ||
| // Called from native. The asyncId stack handling is taken care of there | ||
| // before this is called. | ||
| return function(asyncId) { |
There was a problem hiding this comment.
Have we verified how this'll change the stack trace from any of these? If V8 can properly infer the name based on the variable name then great.
There was a problem hiding this comment.
It does that on the newer v8 versions:
> const a = { foo: function () {}, bar() {}, baz: () => {} }
undefined
> a.foo.name
'foo'
> a.bar.name
'bar'
> a.baz.name
'baz'But I am not certain if there might be a context in which it is not inferred. I am also not sure where to trigger a stack trace from one of these functions as I didn't look deep into the async_hooks code so far. Can you point me out to something or give me a small example?
I could enforce setting the name though.
function hookFactory(symbol, name) {
const fn = function () {}
Object.defineProperty(fn, 'name', {
value: name
})
return fn
}
const hook = hookFactory(Symbol(), 'myName')There was a problem hiding this comment.
The stack trace was changed so I now explicitly set the name and it's now looking good again.
Error
at AsyncHook.before (repl:2:26)
at emitBeforeN (async_hooks.js:358:40)
at emitBeforeS (async_hooks.js:393:3)
at nextTickEmitBefore (internal/process/next_tick.js:158:7)
at process._tickDomainCallback (internal/process/next_tick.js:230:9)
|
PTAL |
lib/async_hooks.js
Outdated
| const before_symbol = Symbol('before'); | ||
| const after_symbol = Symbol('after'); | ||
| const destroy_symbol = Symbol('destroy'); | ||
| const emitBeforeN = emitHookFactory(before_symbol); |
There was a problem hiding this comment.
Question: is there a need to declare these? Stack beauty?
Otherwise could just be used in L#61
There was a problem hiding this comment.
Only the emitDestroyN hook is used only once, the other two are used in more than one spot. I made them all const for consistency.
| } | ||
| } | ||
| } catch (e) { | ||
| fatalError(e); |
There was a problem hiding this comment.
You asked how to reach this fatalError call. The following will do it:
require('async_hooks').createHook({
before() { throw new Error('ah crud') },
}).enable();
setTimeout(() => {}, 10);|
Comment addressed |
lib/async_hooks.js
Outdated
| const before_symbol = Symbol('before'); | ||
| const after_symbol = Symbol('after'); | ||
| const destroy_symbol = Symbol('destroy'); | ||
| const emitBeforeN = emitHookFactory(before_symbol, 'emitBeforeN'); |
There was a problem hiding this comment.
Could you change the N to Native while you are at it? That short naming convention really annoys me.
There was a problem hiding this comment.
I guess in that case the the S should also be renamed but I can't think of what it stands for right now. Does it stand for Script?
| restoreTmpHooks(); | ||
| } | ||
| }; | ||
| Object.defineProperty(fn, 'name', { |
There was a problem hiding this comment.
Mind leaving a comment that explains this sets the anonymous function name such it looks good in stack traces.
|
@trevnorris why is
@BridgeAR If the above is true, please also rename |
|
@AndreasMadsen I'm not sure if we can factorize init as it calls the hooks with |
Haha, completly forgot about that, never mind :) |
|
landed in 5c6c029 |
PR-URL: #13755 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
PR-URL: #13755 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
This fixes an error that could occure by nesting async_hooks calls PR-URL: #14054 Ref: #13755 (comment) Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
PR-URL: #13755 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
This fixes an error that could occure by nesting async_hooks calls PR-URL: #14054 Ref: #13755 (comment) Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
The difference between the hooks is only a single variable and it can be initialized in the beginning. So I think it's nicer to stick to DRY.
The
initfunction is also very similar but that would require an additional check, so I kept it as it is.I also added a
TODOentry as the comment somewhat confused me (ping @trevnorris ).Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
async_hooks