Есть ли способ запускать модули машинного кода с использованием рабочих потоков?

#node.js #node-worker-threads

Вопрос:

Можно ли использовать модули собственного кода в рабочих потоках?

Я создаю каждый рабочий поток, как показано на рисунке:

 const { Worker } = require("worker_threads");
const auth = require("./auth.json");

const shardIds = [...Array(auth.shards).keys()];

for (let i = 0; i < shardIds.length; i  ) {
    setTimeout(() => {
        new Worker("./bot.js", { workerData: { shardIds: [shardIds[i]], totalShards: auth.shards }});
    }, i * 5000);
}
 

…что, похоже, работает просто отлично. Запуск одного рабочего потока не вызывает проблем.

Однако при создании нескольких работников возвращается эта ошибка:

 Error: Module did not self-register: '\?C:[file path]node_moduleserlpackbuildReleaseerlpack.node'.
 

Это является результатом необходимости использования модуля «erlpack» во втором потоке.

Немного поискав решения этой проблемы, оказалось, что я не единственный, у кого возникли трудности с использованием модулей, которые включают собственный код более чем в одном потоке.

Я попытался перестроить модули, переустановить модули и даже запросить модуль в файле, который создает рабочих, и передать его через «Рабочие данные» (что не сработало). Я также пробовал его на разных устройствах, под управлением разных операционных систем (Ubuntu и Windows), а также установил параметр «win_delay_load_hook» в binding.gyp файле для этого модуля в значение «true».

К сожалению, я не смог найти никакого рабочего решения.

Возможно ли вообще это сделать? Или есть другой способ создать несколько процессов, имея возможность передавать данные в каждый процесс, что также позволяет использовать модули собственного кода?

Ответ №1:

Проблема заключалась в том, что модуль не был «осведомлен о контексте».

Эта строка:

NODE_МОДУЛЬ

Пришлось изменить на:

NAN_MODULE_WORKER_ENABLED

…в js/erlpack.cc файле, чтобы он мог работать с потоками.