Узел 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 декодирование битов.

Другие вопросы по тегам