DenoのWeb Workerの処理を読む
- publishedAt:
- 2025/12/02
- updatedAt:
- 2025/12/02
Intro
この記事はDeno Advent Calendar 2025の2日目の記事です。
少し前に、Agentsを理解したい というブログを書いた。
これはWeb Workerの実装のためだったが、今回は具体的にWeb Workerのコードを読んでいきたい
Web Workerを理解する
まずゴールをきめたい。以下のような簡単なworkerコードがどのようにDenoは動かされているのかをざっくり理解したい。
// main.ts
const worker = new Worker(
new URL("./worker.ts", import.meta.url).href,
{ type: "module" },
);
worker.postMessage({
filename: new URL("./log.txt", import.meta.url).pathname
});
// worker.ts
self.onmessage = async (e) => {
const { filename } = e.data;
const text = await Deno.readTextFile(filename);
self.close();
};
new Worker
まずはnew Workerの処理をイメージしてみる。constructorがあるはず。
https://github.com/denoland/deno/blob/355d8994b2ab3b4979214d6d47ed70e39a37a92c/runtime/js/11_workers.js#L94-L140 でconstructorを定義している
その中でcreateWorkerという関数をさらに読んでいる。これが
その中を見ていると、run_web_workerが見つかる。
ただここではすでにisolate(変数名ではworker)が渡されているので、worker用のisolateの呼び出しはその前の以下であることがわかる
これはちょっと自分のRustの知識不足で苦戦したのだが、これはどうやらクロージャーという方法を活用しているらしい。
https://doc.rust-jp.rs/book-ja/ch13-01-closures.html
事前に定義された関数をここではstateに格納して、それを再度呼び出している。
では一番最初にどこでisolateを作っているかというと、以下になる。
deno run index.tsとかdeno index.tsとかしたときにjavascriptを動かすためのmainスレッドの呼び出しでこのメソッドは実行される。
そしてクロージャーの登録は以下で行われる。
わかりづらいので整理すると以下のようになる
1. deno run main.ts // cliで実行
2. MainWorker(main.ts)// main.tsを動かすためのagent(isolate)が作られる
3. Web Worker(new Worker("./worker.ts"))// workerを動かすためのagent(isolate)が作られる
クロージャーの概念が全然わかってなかったので、ここは結構苦戦した。
ここまででやっとnew Workerのざっくり処理が理解できた。
worker.postMessage
次に指定したスレッドへデータを送信する仕組みを理解する。
jsとrustのpostMessage関連の処理は以下になる
jsはrustにパラメーター渡すための整形を行っている感じ。実態はrust側にあるよう。
op_host_post_messageの中にあるsendメソッドは以下。
どうやらtokioを使って作られてる。
送るスレッドはどうやって決めているのだろうか?例えばworkerがAとBの二つあったときに、mainからAに送る指定の方法が知りたい
ここで見逃していたが、WorkersTableというものがある。
idでgetしているだけで、さっきのインスタンス作成時にworker_idというものを作っていた。
なのでclass内にprivate fieldとして定義されていたこの値をrust側に渡して、メモリから引っ張ってきている感じということがわかった。とてもシンプルで直感的な処理である。
self.onmessage || worker.onmessage
さて最後に渡されたデータの受け取り方を見ていきたい。
これはMainWorkerとself.onmessageで呼び出した時に呼ばれる箇所が異なる。
self.onmessageは以下になる
そしてworker.onmessageは以下になる
workerインスタンス作成時にこれらのメソッドが呼び出され、pollingするようになっている。
具体的なonmessageの処理探すの結構苦戦した。
終わりに
Denoのコードがわかりやすいように作られていて助かった。
これらを参考にAndromedaでnew Workerを組み込んでいく。
DenoのWeb Workerの処理を読む
- publishedAt:
- 2025/12/02
- updatedAt:
- 2025/12/02
0