はじめに
2023年12月17日分のアドベントカレンダーの記事になります。
以下記事の続きになります。
【L1、L2】ブラウザでWorkerを動かしてみる(基本編)
https://qiita.com/k-kawashima/items/0bc4b862c0a91c2fdf99
前回は、短いコードでWorkerを動作させてみました。
今回はこのワーカーを更に便利に動作させる為のモジュールであるworkerpoolを利用してみます。
workerpool
https://www.npmjs.com/package/workerpool
workerpoolってどんなモジュール?(ChatGPTに聞いてみた)
Node.js のワーカープールを簡単に作成できるパッケージです。ワーカー内で実行する関数を指定し、非同期にタスクを実行できます。
上記のような回答が得られました。このモジュールを利用してよいところは以下になります。
特に、3,4,5は便利で、自分で処理をラップして同じようなことをしなくてもよいので楽ちん!
- 1:ワーカーにて実行させたい処理群をこのモジュール内に集中して管理できる。
- 2:ページ内のどこでもこのモジュールを通してアクセスできるのでわざわざワーカーのインスタンスを管理する必要がない。
- 3:ワーカーに実行させたい処理を別スクリプトに移す必要がない。
- 4:Promiseとして処理を実行できるのでコードが簡潔になる。
- 5:ワーカーの実行数、タイムアウト、キャンセル、停止等を実行可能。
この記事で分かること
- 専用ワーカーを使いやすくするwokerpoolモジュールの利用方法。(こちら番外編として別記事にして記載します)
準備
確認環境は前回の「【L1、L2】ブラウザでWorkerを動かしてみる(基本編)」をそのまま利用します。
追加のモジュールをインストールしまましょう。
pnpm install workerpool
確認コードの作成
workpoolを静的ファイルから参照できるようにしましょう。
src/server.tsを以下内容で追加します。
import fastify from "fastify";
import fastifyStatic from "@fastify/static";
import path from "path";
const server = fastify();
server.register(fastifyStatic, {
root: path.join(process.cwd(), "public"),
});
// 以下を追加。静的ファイルからworkerpoolを読込めるようにする
server.register(fastifyStatic, {
root: path.join(process.cwd(), "node_modules/workerpool/dist"),
prefix: "/workerpool/dist",
decorateReply: false,
});
server.get("/ping", async (request, reply) => {
return "Hellow world\n";
});
server.listen({ port: 18080 }, (err, address) => {
if (err) {
console.error(err);
process.exit(1);
}
console.log(`server is listening at ${address}`);
});
content/example2.htmlを以下内容で追加します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>ワーカーテスト2</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="data:," />
</head>
<body>
<div>これはテスト2です。</div>
<button id="btn1">ワーカーにデータを送信します。</button>
<div>ワーカーから受信したデータは以下です。</div>
<div id="received_data"></div>
</body>
<!-- workerpoolモジュールを読み込んでおく -->
<script src="/workerpool/dist/workerpool.js"></script>
<script>
//import workerpool from "workerpool";
const pool = workerpool.pool({ maxWorkers: 20 });
// 何かしら時間のかかる処理
// 但し、worker内ではDOMを操作できないので、APIのアクセスや、負荷の高い計算がなどの処理を移譲する。
function sleep_func(duration) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, duration);
});
}
(async function () {
await pool
// ワーカーに引数を渡して処理を実行する。
.exec(sleep_func, [2000])
// ワーカー処理結果が正常終了の場合に実行したい処理を記載する
.then(function () {
console.log("finished sleep(2000)");
})
// ワーカー処理結果の例外発生した場合に実行したい処理を記載する
.catch(function (err) {
console.error(err);
});
})();
</script>
</html>