I'm using AsyncWorker
to run an asynchronous task. The problem is that i have numerous tasks to be run, one after another, and the order is important. To keep order i'm using a queuing technique to make sure the AsyncWorker
objects are created in the wright order, only once each task finishes. I'm storing the Callback in a vector<Function>
, and pass that to the AsyncWorker
, but i get the following error:
# Fatal error in v8::HandleScope::CreateHandle()
# Cannot create a handle without a HandleScope
Is there some other way of going about this? I also tried using Napi::Persistent
, but i can't pass a Napi::FunctionReference
variable to AsyncWorker
The caller functions:
Napi::Value BlockChainWrapper::genesis(const Napi::CallbackInfo& info) {
std::lock_guard<std::mutex> guard_ready_queue(ready_queue_mutex);
this->ready_queue_callback.push_back(info[1].As<Napi::Function>());
this->ready_queue_data.push_back(info[0].As<Napi::Object>());
this->ready_queue_func.push_back(BlockChainWrapperTypes::_genesis_ready);
this->ready_queue_env.push_back(info.Env());
return info.Env().Undefined();
}
void BlockChainWrapper::genesis_ready() {
AsyncBlockChainFunctions* asyncWorker = new AsyncBlockChainFunctions(this->ready_queue_callback.front(), 0, blockchain_obj, this->ready_queue_data.front());
asyncWorker->Queue();
}
AsyncWorker constructor:
AsyncBlockChainFunctions::AsyncBlockChainFunctions(Napi::Function& callback, int mode, std::shared_ptr<BlockChain> _blockchain, Napi::Object& resource) : AsyncWorker(callback), mode(mode) {};
EDIT 1 I implemented the PromiseWorker, but still ran into these errors: BlockChainWrapper inherits ObjectWrap.
Napi::Object BlockChainWrapper::Init(Napi::Env env, Napi::Object exports) {
Napi::HandleScope scope(env);
Napi::Function func = DefineClass(env, "BlockChainWrapper", {
InstanceMethod("genesis", &BlockChainWrapper::genesis)
});
constructor = Napi::Persistent(func);
constructor.SuppressDestruct();
exports.Set("BlockChainWrapper", func);
return exports;
}
# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place
Modified AsyncWorker constructor, class and resolve function:
class AsyncBlockChainFunctions : public PromiseWorker
AsyncBlockChainFunctions(Napi::Promise::Deferred const &d, std::shared_ptr<BlockChain> _blockchain, int mode, Napi::Object& resource) : PromiseWorker(d), mode(mode) {}
void Resolve(Napi::Promise::Deferred const &deferred) {
deferred.Resolve(Napi::String::New(deferred.Env(), this->block_as_json_string));
};
Caller function:
Napi::Value BlockChainWrapper::genesis(const Napi::CallbackInfo& info) {
std::lock_guard<std::mutex> guard_ready_queue(ready_queue_mutex);
this->ready_queue_data.push_back(info[0].As<Napi::Object>());
this->ready_queue_func.push_back(BlockChainWrapperTypes::_genesis_ready);
this->ready_queue_env.push_back(info.Env());
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(info.Env());
std::cout << "genesis" << std::endl;
return deferred.Promise();
}
Genesis ready called from another queue management thread
void BlockChainWrapper::genesis_ready() {
Napi::Env env = ready_queue_env.front();
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
Napi::Object input_obj = this->ready_queue_data.front().As<Napi::Object>();
auto *x = new AsyncBlockChainFunctions(std::ref(deferred), this->blockchain_obj, 0, input_obj);
x->Queue();
}