src,async_hooks,n-api: refactor async callback handling#14697
src,async_hooks,n-api: refactor async callback handling#14697addaleax wants to merge 8 commits intonodejs:masterfrom
Conversation
|
N-API parts look good. I'm still planning to add an async context parameter to If I'm understanding correctly, the change in this PR means that when the N-API async work APIs are used, during the |
|
@jasongin This PR would mean that |
|
Oh, so the async work callback should just call Then the only need for |
|
In that case should |
|
@jasongin Exactly 👍
Right. Done! |
4dceb50 to
c5cc1cf
Compare
65dfc41 to
b7f6ca7
Compare
|
Rebased … maybe somebody of @AndreasMadsen @trevnorris @refack @TimothyGu @tniessen @bnoordhuis @jasnell could be reviewer (if only for the yet-unreviewed non-N-API part)? |
doc/api/n-api.md
Outdated
|
@trevnorris I think all your comments have been addressed or answered so far. Since others in the N-API team have expressed the desire – and I agree – for the breaking N-API changes to get out sooner rather than later, I would like to have the option of landing this soon so it can go into 8.5.0 (unless anybody sees glaring issues with it). That doesn’t mean we can’t make modifications to the internals later. If you think this is a terrible idea, I’d open a PR that contains just the breaking API changes of this one without any wiring behind them. |
|
@addaleax Mind verifying some of the following implementation details? In node::CallbackScope(isolate, args[0].As<v8::Object>(), asyncContext);
v8::Local<v8::Function> fn = args[3].As<v8::Function>();
v8::MaybeLocal<v8::Value> ret =
fn->Call(isolate->GetCurrentContext(), args[0], 0, nullptr);Which appears to indicate that the user can always call
So there's a scenario where both |
|
@addaleax The following is a discrepancy between using C++ code for test module#include <v8.h>
#include <node.h>
namespace bmod {
using namespace v8;
static void RunCallbackScope(const FunctionCallbackInfo<Value>& args) {
assert(args[0]->IsNumber());
assert(args[1]->IsNumber());
assert(args[2]->IsFunction());
assert(args[3]->IsObject());
auto isolate = args.GetIsolate();
auto ctx = isolate->GetCurrentContext();
double a_id = args[0]->NumberValue();
double t_id = args[1]->NumberValue();
auto fn = args[2].As<Function>();
auto obj = args[3].As<Object>();
node::CallbackScope(isolate, obj, { a_id, t_id });
auto ret = fn->Call(ctx, obj, 0, nullptr);
if (ret.IsEmpty()) {
fprintf(stderr, "fn call failed\n");
}
}
static void RunMakeCallback(const FunctionCallbackInfo<Value>& args) {
assert(args[0]->IsNumber());
assert(args[1]->IsNumber());
assert(args[2]->IsFunction());
assert(args[3]->IsObject());
auto isolate = args.GetIsolate();
double a_id = args[0]->NumberValue();
double t_id = args[1]->NumberValue();
auto fn = args[2].As<Function>();
auto obj = args[3].As<Object>();
auto ret = node::MakeCallback(isolate, obj, fn, 0, nullptr, { a_id, t_id });
if (ret.IsEmpty()) {
fprintf(stderr, "fn call failed\n");
}
}
void Init(Local<Object> exports) {
NODE_SET_METHOD(exports, "runMakeCallback", RunMakeCallback);
NODE_SET_METHOD(exports, "runCallbackScope", RunCallbackScope);
}
} // namespace bmod
NODE_MODULE(addon, bmod::Init)Here is the JS that uses the source above: 'use strict';
const release_type = process.config.target_defaults.default_configuration;
const { runCallbackScope, runMakeCallback } = require(`./build/${release_type}/addon`);
const async_hooks = require('async_hooks');
const { executionAsyncId, triggerAsyncId } = async_hooks;
const print = process._rawDebug;
async_hooks.createHook({
before(id) { print('before: ', id); },
after(id) { print('after: ', id); },
}).enable();
const obj = {};
function fn() {
print(`asyncId: ${executionAsyncId()}\ttriggerId: ${triggerAsyncId()}`);
}
runCallbackScope(42, 43, fn, obj);
runMakeCallback(42, 43, fn, obj);Output from the test: Issue is the global values returned by |
|
@trevnorris That latter problem is a typo in the test file; I fixed it here now. You need to give the Re: Disposed domains … sigh. We should remove those in Node 10. But you’re right, the API should provide for that; I’m thinking something along |
Whoops. Thanks.
We might just make the case that supporting a deprecated API in a deprecated module isn't necessary. Especially if it means support requires an additional API. Though not sure who we'd need to confirm that with. |
@trevnorris I would agree :) I would be fine with just seeing if anybody complains. After all, |
|
i.e. I’ll open a semver-major PR to remove it once this lands. |
`node_internals.h` already includes the most common headers, so double includes can be avoided in a lot of cases. Also don’t include `node_internals.h` from `node.h` implicitly anymore, as that is mostly unnecessary. PR-URL: nodejs#14697 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#14697 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
- Merge the two almost-but-not-quite identical `MakeCallback()` implementations - Provide a public `CallbackScope` class for embedders in order to enable `MakeCallback()`-like behaviour without tying that to calling a JS function PR-URL: nodejs#14697 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: nodejs#14697 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Enable combining N-API async work with async-hooks. PR-URL: nodejs#14697 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Michael Dawson <mhdawson@ibm.com>
With `CallbackScope`, this has become possible to do properly. Fixes: nodejs#5691 PR-URL: nodejs#14697 Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
|
Rebased due to conflicts with 35a526c, one more CI: https://ci.nodejs.org/job/node-test-commit/12360/ I would like to land this if it comes back green |
|
Landed in 4ae0afb...1a0727d @trevnorris Feel free to add more comments/ask questions, I’d be happy to address those in subsequent PRs; at this point, I think the PR is quite plainly ready, and it’s good to get the last batch of breaking N-API commits out in the next release. |
|
@addaleax looks good. thanks for waiting for my feedback despite my delays. |
MakeCallback()implementationsCallbackScopeclass for embedders in order to enableMakeCallback()-like behaviour without tying that to calling a JS functionChecklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
/cc @nodejs/async_hooks
/cc @nodejs/n-api (Who may or may not only want to review the N-API commit; this is a breaking N-API change)