Я разрабатываю приложение Node.js, которое включает в себя Windows DLL.DLL управляет научным оборудованием, для контекста.
Мой интерфейс от Node к DLL работает хорошо, однако DLL имеет некоторые недетерминированные вызовы, которые зависят от топологии сети и радиочастотных сигналов в комнате.Эти вызовы могут занимать от 10 секунд до 10 минут.
Я бы хотел отключить эти вызовы от цикла обработки событий Node и даже избегать AsyncWorkers.Я хотел бы поместить их в свои собственные потоки C ++.Я беспокоюсь, что не знаю достаточно Node / V8, чтобы правильно подойти к проблеме, хотя я уже дважды пытался это сделать.
Ниже приведена моя попытка создать поток для вызова обратного вызова js, хотя яЯ не уверен, что это хороший подход.Мне нужен результат вызова, и у меня до сих пор есть «демон» в приложении моего узла, который регулярно проверяет результаты поиска выполненных задач.
mTp
во фрагменте ниже:реализация пула потоков, которую я написал.Runtask принимает лямбда-код C ++ в качестве параметра для добавления в мою очередь рабочих потоков.mThreadStatus - это карта из моего дескриптора потока, который является строкой, в перечисление thread_status_t.mThreadResults - это еще одна карта из дескриптора потока в v8 :: Value, которая возвращается обратным вызовом.
void
MyObj::SpawnThread(functionInput info) {
MyObj* obj = ObjectWrap::Unwrap<MyObj>(info.Holder());
obj->mTp.RunTask([&]() {
v8::Isolate::CreateParams cp;
v8::Isolate* tpIsolate = v8::Isolate::New(cp);
v8::Locker locker(tpIsolate);
v8::Isolate::Scope isolateScope(tpIsolate);
Nan::HandleScope scope;
auto global = obj->mContext.Get(tpIsolate)->Global();
auto handle = std::string(*v8::String::Utf8Value(info[0]->ToString()));
{
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = thread_status_t::running;
}
v8::Handle<v8::Function> f = v8::Handle<v8::Function>::Cast(info[1]);
v8::TryCatch trycatch(tpIsolate);
v8::Handle<v8::Value> result = f->Call(global, 0, nullptr);
if (result.IsEmpty()) {
v8::Local<v8::Value> exception = trycatch.Exception();
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = thread_status_t::error;
return;
}
{
std::unique_lock<std::shared_mutex> resultLock(obj->mThreadResultsMutex);
obj->mThreadResults[handle] = result;
}
std::unique_lock<std::shared_mutex> lock(obj->mThreadStatusMutex);
obj->mThreadStatus[handle] = completed;
tpIsolate->Dispose();
});
Я предполагаю, что мои js выглядят так, чтобы порождать поток:
var ctx = this
this.myObj.spawnThread('startMeasurements', () => {
return ctx.myObj.startMeasurements()
})
И вот так, чтобы получить результат, в моем 'демоне':
var status = this.myObj.getThreadStatus('startMeasurements')
if ( status === 'complete') {
// Publish returned information to front-end
}
else if (status === 'error') {
// Handle error
}
Кто-нибудь раньше решал эту проблему?Это похоже на достойный подход?Помощь с v8 очень ценится.Спасибо!