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を使ってみる
1. 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);
});
2. Node-RED上でfunctionノードを配置
続いて、Node-RED上にfunctionノードを配置し、worker_threads
の設定を行っていきます。
worker_threads
モジュールの読込み
3. functionノードの設定タブにてworker_threads
モジュールを設定します。(インポート名は任意)
4. 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);
5. workerへデータを送信する
functionノードのコードタブを下記のように記載し、worker
へmsg
オブジェクトを送信します。
// コンテキストからworkerを取得
const worker = context.get("worker");
// workerへmsgオブジェクトを送出
worker.postMessage(msg);
// workerからの返却値を送出するためmsgの返却を抑止
return null;
6. 動作確認
下記のようにinjectノードとdebugノードを繋げて、動作確認します。
injectノードではpayload
に適当な文字列を設定し、debugノードではpayloadを表示させています。
実行するとworkerで処理されたメッセージが表示されていることが確認できます。
また、コンソールでは下記のようにworker.js
に記載した値が出力されていることが確認できます。
おわりに
勉強も兼ねてNode-REDでworker_threads
が利用できないかと思い実装してみましたが、
ちょっとでもworker側でエラーが発生するとNode-REDもまるごと落ちてしまうので、
使い所が難しいかなと感じました。
Discussion