Understanding Nan::AsyncResource
matteodisabatino opened this issue · 1 comments
matteodisabatino commented
Hi,
I'm trying to develop a node.js addon in C++ using nan in order to reproduce this behaviour:
console.log('MyModule: ', MyModule);
MyModule.on('data', (...args) => {
console.log('on data args: ', args)
})
MyModule.on('data', (...args) => {
console.log('on data 2 args: ', args)
})
MyModule.on('wrong-event', (...args) => {
console.log('on wrong-event args: ', args)
})
If I write the addon this way:
#include <nan.h>
class GCAsyncResource : public Nan::AsyncResource
{
public:
GCAsyncResource(v8::Local<v8::Function> callback_)
: Nan::AsyncResource("event-callback")
{
callback.Reset(callback_);
}
~GCAsyncResource()
{
callback.Reset();
}
Nan::Persistent<v8::Function> callback;
};
static GCAsyncResource *gc_async_resource;
NAN_METHOD(on)
{
if (info.Length() != 2)
{
return;
}
if (!info[0]->IsString())
{
return;
}
if (std::string(*Nan::Utf8String(info[0])) != "data")
{
return;
}
if (!info[1]->IsFunction())
{
return;
}
v8::Local<v8::Function> cb = Nan::To<v8::Function>(info[1]).ToLocalChecked();
gc_async_resource = new GCAsyncResource(cb);
v8::Local<v8::Value> cb_arguments[] = {
Nan::New("hello world!!").ToLocalChecked()};
v8::Local<v8::Function> callback = Nan::New(gc_async_resource->callback);
v8::Local<v8::Object> target = Nan::New<v8::Object>();
gc_async_resource->runInAsyncScope(target, callback, 1, cb_arguments);
}
NAN_MODULE_INIT(init)
{
Nan::HandleScope scope;
Nan::Set(target,
Nan::New("on").ToLocalChecked(),
Nan::GetFunction(
Nan::New<v8::FunctionTemplate>(on))
.ToLocalChecked());
}
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
I receive this output: (the output it's correct since is exactly what I excpeted)
MyModule: { on: [Function (anonymous)] }
on data args: [ 'hello world!!' ]
on data 2 args: [ 'hello world!!' ]
After, I've tried to extend my code in order to get data from garbage collection:
#include <nan.h>
class GCAsyncResource : public Nan::AsyncResource
{
public:
GCAsyncResource(v8::Local<v8::Function> callback_)
: Nan::AsyncResource("event-callback")
{
callback.Reset(callback_);
}
~GCAsyncResource()
{
callback.Reset();
}
Nan::Persistent<v8::Function> callback;
};
static GCAsyncResource *gc_async_resource;
NAN_GC_CALLBACK(onGCPrologue)
{
// Things...
}
NAN_GC_CALLBACK(onGCEpilogue)
{
// Things...
v8::Local<v8::Value> cb_arguments[] = {
Nan::New("hello world!!").ToLocalChecked()};
v8::Local<v8::Function> callback = Nan::New(gc_async_resource->callback);
v8::Local<v8::Object> target = Nan::New<v8::Object>();
gc_async_resource->runInAsyncScope(target, callback, 1, cb_arguments);
}
NAN_METHOD(on)
{
if (info.Length() != 2)
{
return;
}
if (!info[0]->IsString())
{
return;
}
if (std::string(*Nan::Utf8String(info[0])) != "data")
{
return;
}
if (!info[1]->IsFunction())
{
return;
}
v8::Local<v8::Function> cb = Nan::To<v8::Function>(info[1]).ToLocalChecked();
gc_async_resource = new GCAsyncResource(cb);
Nan::AddGCEpilogueCallback(onGCEpilogue);
}
NAN_MODULE_INIT(init)
{
Nan::HandleScope scope;
Nan::AddGCPrologueCallback(onGCPrologue);
Nan::Set(target,
Nan::New("on").ToLocalChecked(),
Nan::GetFunction(
Nan::New<v8::FunctionTemplate>(on))
.ToLocalChecked());
}
NODE_MODULE(NODE_GYP_MODULE_NAME, init)
I expected to receive events in this case too, instead the only thing I can read on console is:
MyModule: { on: [Function (anonymous)] }
I really don't know what am I wronging. May the problem stand on the class GCAsyncResource?
If it could be useful, I'm using:
- node: v14.15.4
- nan: v2.14.2
- node-pre-gyp: v0.17.0
matteodisabatino commented
I solved my problem by own.