40 lines
1.2 KiB
TypeScript
40 lines
1.2 KiB
TypeScript
import type { FromChunkWorker, ToChunkWorker } from "./workers/chunk_messages.ts";
|
|
|
|
// leave a core for the main thread, more than 4 doesnt help much
|
|
const POOL_SIZE = Math.max(1, Math.min(4, (navigator.hardwareConcurrency ?? 4) - 1));
|
|
|
|
export class ChunkWorkerPool {
|
|
readonly size = POOL_SIZE;
|
|
#workers: Worker[] = [];
|
|
#next = 0;
|
|
|
|
constructor(on_message: (message: FromChunkWorker) => void) {
|
|
for (let i = 0; i < this.size; i += 1) {
|
|
const worker = new Worker(new URL("./workers/chunk_worker.js", import.meta.url), { type: "module" });
|
|
worker.onmessage = (event: MessageEvent<FromChunkWorker>) => on_message(event.data);
|
|
worker.onerror = (event) => console.error("Chunk worker error:", event.message);
|
|
this.#workers.push(worker);
|
|
}
|
|
}
|
|
|
|
broadcast(message: ToChunkWorker) {
|
|
for (const worker of this.#workers) {
|
|
worker.postMessage(message);
|
|
}
|
|
}
|
|
|
|
// round robin, results can come back out of order
|
|
post(message: ToChunkWorker, transfer: Transferable[] = []) {
|
|
const worker = this.#workers[this.#next];
|
|
this.#next = (this.#next + 1) % this.#workers.length;
|
|
worker.postMessage(message, transfer);
|
|
}
|
|
|
|
terminate() {
|
|
for (const worker of this.#workers) {
|
|
worker.terminate();
|
|
}
|
|
this.#workers = [];
|
|
}
|
|
}
|