mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-16 10:39:53 +00:00
Rework fallback for postMessage issue
Now initialise all workers with module+memory separately, and then instead of using postMessage to send thread pointers, push them into a crossbeam-deque on the Rust side. Rayon already depends on crossbeam-dequeue, so we're not even adding another dependency, and this model allows us to push "tasks" (thread pointers) on the main thread and pop them on worker threads in arbitrary order without sacrificing correctness.
This commit is contained in:
committed by
Ingvar Stepanyan
parent
4c658b79ef
commit
0747d2c419
@@ -1,32 +1,23 @@
|
||||
let main = new Worker("./main.js", { type: "module" });
|
||||
import initOxiPNG, { worker_initializer, start_main_thread, optimise } from './pkg/oxipng.js';
|
||||
import wasmUrl from "./pkg/oxipng_bg.wasm";
|
||||
|
||||
let workers = Array.from(
|
||||
{ length: navigator.hardwareConcurrency },
|
||||
() => new Worker("./worker.js", { type: "module" })
|
||||
);
|
||||
|
||||
main.addEventListener('message', ({ data: { type, data } }) => {
|
||||
if (type === 'spawn') {
|
||||
workers.pop().postMessage(data);
|
||||
async function startMainThread() {
|
||||
let num = navigator.hardwareConcurrency;
|
||||
await initOxiPNG(fetch(wasmUrl));
|
||||
let workerInit = worker_initializer();
|
||||
let workers = [];
|
||||
for (let i = 0; i < num; i++) {
|
||||
workers.push(new Promise(resolve => {
|
||||
let worker = new Worker("./worker.js", { type: "module" });
|
||||
worker.postMessage(workerInit);
|
||||
worker.addEventListener('message', resolve, { once: true });
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
let ID = 0;
|
||||
|
||||
export function optimise(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let sendId = ID++;
|
||||
|
||||
main.addEventListener('message', function onMessage({ data: { ok, id, result } }) {
|
||||
if (id !== sendId) return;
|
||||
main.removeEventListener('message', onMessage);
|
||||
if (ok) {
|
||||
resolve(result);
|
||||
} else {
|
||||
reject(result);
|
||||
}
|
||||
});
|
||||
|
||||
main.postMessage({ id: sendId, args });
|
||||
});
|
||||
await Promise.all(workers);
|
||||
start_main_thread(num);
|
||||
return {
|
||||
optimise
|
||||
};
|
||||
}
|
||||
|
||||
export default startMainThread();
|
||||
|
||||
Reference in New Issue
Block a user