Node-REDでworker_threadsを使用する
はじめに
Node-REDでworker_threadsが利用できるか試した際の記録です。
(Docker上のNode-REDで検証)
Node-REDでworker_threadsが必要になった際にご活用ください。
検証環境
- Node.js: 18.18.1
- Node-RED: 3.1.0
Node-REDからworker_threadsを使ってみる
workerの処理を作成する
はじめにNode-REDから呼び出すworkerの処理を作成しておきます。
下記のようなスクリプトを作成し、Node-REDから読込み可能なディレクトリに配置します。
(今回はNode-REDのルートディレクトリ上に配置しています。)
const { parentPort } = require('worker_threads');
// Node-REDからのメッセージを取得
parentPort.on('message', async msg => {
// Node-REDからのメッセージを表示
console.log(msg.payload);
// msg.payloadに値を設定
msg.payload = 'I am worker!!!';
// Node-REDへmsgオブジェクトを返却
parentPort.postMessage(msg);
});
Node-RED上でfunctionノードを配置
続いて、Node-RED上にfunctionノードを配置し、worker_threadsの設定を行っていきます。

worker_threadsモジュールの読込み
functionノードの設定タブにてworker_threadsモジュールを設定します。(インポート名は任意)

workerからデータを受信する
functionノードの初期化処理タブにて下記のようにworkerからmsgオブジェクトを受け、msgオブジェクトを後続のノードへ送出する処理を記載します。
読込みを行うjsファイル(workerでの処理を記載したファイル)はNode-REDのルートディレクトリからの相対パスか絶対パスで指定します。
また、生成したworkerオブジェクトはコードタブや終了処理タブでも扱えるようにコンテキストへ保持します。

const { Worker } = workerThreads;
const worker = new Worker('./workers.js');
// workerからのメッセージを待機
worker.on('message', workerMsg => {
// workerから送信されたmsgオブジェクトを送出
node.send(workerMsg);
});
// コンテキストにworkerを保持
context.set('worker', worker);
workerへデータを送信する
functionノードのコードタブを下記のように記載し、workerへmsgオブジェクトを送信します。

// コンテキストからworkerを取得
const worker = context.get('worker');
// workerへmsgオブジェクトを送出
worker.postMessage(msg);
// workerからの返却値を送出するためmsgの返却を抑止
return null;
動作確認
下記のようにinjectノードとdebugノードを繋げて、動作確認します。
injectノードではpayloadに適当な文字列を設定し、debugノードではpayloadを表示させています。
実行するとworkerで処理されたメッセージが表示されていることが確認できます。

また、コンソールでは下記のようにworker.jsに記載した値が出力されていることが確認できます。

おわりに
勉強も兼ねてNode-REDでworker_threadsが利用できないかと思い実装してみましたが、
ちょっとでもworker側でエラーが発生するとNode-REDもまるごと落ちてしまうので、
使い所が難しいかなと感じました。
Discussion