Workers

DenoはWeb Worker APIをサポートしています。

Workerを使用して、複数のスレッドでコードを実行できます。 Workerの各インスタンスは、そのWorker専用の個別のスレッドで実行されます。

現在、DenoはモジュールタイプのWorkerのみをサポートしています。したがって、新しいWorkerを作成するときは、type: "module"オプションを渡すことが不可欠です。

現在のところ、相対モジュール指定子はサポートされていません。代わりに、URLコンストラクターとimport.meta.urlを使用して、近くにあるスクリプトの指定子を簡単に作成できます。

// Good
new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });

// Bad
new Worker(new URL("worker.js", import.meta.url).href);
new Worker(new URL("worker.js", import.meta.url).href, { type: "classic" });
new Worker("./worker.js", { type: "module" });

パーミッション

新しいWorkerインスタンスの作成は、動的インポートに似ています。したがって、Denoはこのアクションに適切な許可を必要とします。

ローカルモジュールを使用するWorker向け。 --allow-readパーミッションが必要です。

main.ts

new Worker(new URL("worker.ts", import.meta.url).href, { type: "module" });

worker.ts

console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag

$ deno run --allow-read main.ts
hello world

リモートモジュールを使用するWorker向け。--allow-netパーミッションが必要です:

main.ts

new Worker("https://example.com/worker.ts", { type: "module" });

worker.ts

console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag

$ deno run --allow-net main.ts
hello world

WorkerでのDenoの使用

これは不安定なDeno機能です。不安定な機能の詳細をご覧ください。

デフォルトでは、Deno名前空間はWorkerスコープでは使用できません。

新しいWorkerを作成するときにDeno名前空間に渡すにはdeno:trueオプションを追加します:

main.js

const worker = new Worker(new URL("worker.js", import.meta.url).href, {
  type: "module",
  deno: true,
});
worker.postMessage({ filename: "./log.txt" });

worker.js

self.onmessage = async (e) => {
  const { filename } = e.data;
  const text = await Deno.readTextFile(filename);
  console.log(text);
  self.close();
};

log.txt

hello world
$ deno run --allow-read --unstable main.js
hello world

Deno名前空間がWorkerスコープで使用可能な場合、Workerは親プロセスのパーミッション(--allow-*フラグを使用して指定されたもの)を継承します。

パーミッションをWorkerに対して構成可能にする予定です。