Узел NAN: получение заданной ошибки при вызове GetFromPersistent в методе Execute AsyncWorker
Я создаю собственное расширение для узла, которое включает в себя длительную операцию с обратным вызовом по завершении.
Я передаю буфер узла на вызов. Он содержит полезную нагрузку того, что должно обрабатываться расширением.
Я должен иметь возможность хранить свой буфер в постоянном хранилище в конструкторе AsyncWorker и извлекать его позже, когда мне это нужно.
Этот пример (из набора тестов nan) - это то, на чем я обычно основываю свой код: https://github.com/nodejs/nan/blob/master/test/cpp/bufferworkerpersistent.cpp
Этот тест работает, но он ничего не делает с буфером до метода HandleOKCallback, который мне не очень интересен. Мне нужно получить доступ к буферу во время выполнения метода.
Если я просто добавлю строку в метод Execute () теста, чтобы попытаться получить доступ к буферу, например:
void Execute () {
printf("before GetFromPersistent\n");
v8::Local<v8::Value> handle = GetFromPersistent("buffer");
printf("after GetFromPersistent\n");
printf("buffer @%llux len %ld\n", (uint64_t)node::Buffer::Data(handle), node::Buffer::Length(handle));
Sleep(milliseconds);
}
Я получаю ошибку сегмента при вызове GetFromPersistent.
Мой вопрос: что мне не хватает? Должен ли я быть в состоянии вытащить постоянный объект в метод Execute? Если так, то почему бы и нет?
1 ответ
ОК, я думаю, что ответ "дух", но для других, только начинающих работать с нативными расширениями Node, вот что я теперь понимаю:
Поскольку узел - это один поток, долго выполняющиеся задачи должны выполняться в другом потоке, если они не должны блокировать узел.
Nan использует libuv для управления пулом потоков для выполнения асинхронной работы, которую вы пишете в методе "Execute".
Тем не менее, конструктор вашего AsyncWorker фактически запускается в потоке узла, и запуск HandleOKCallback также запланирован после завершения Execute.
Таким образом, можно получить доступ к ресурсам узла, находясь в конструкторе и в настройке обратного вызова, но поскольку Execute выполняется в другом потоке, это не нормально, поэтому он вызывает ошибки.
Поэтому для моей проблемы (я запускаю декодирование JPEG в AsyncWorker), я вместо этого вытаскиваю указатель и длину из буфера в конструкторе, но все еще вызываю SaveToPersistent в буфере, чтобы он не получал GCed, пока я 'm декодирование битов.