GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.34k stars 390 forks source link

Exposed function deadlocks if called too early #665

Open EarlMilktea opened 3 months ago

EarlMilktea commented 3 months ago

Problem description

Wrapped function does not return when called before the worker is ready.

Minimum codes to reproduce

Deps.

// task.ts: Dummy task
// task.ts

// Dummy task
export async function dummyTask(time: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, time);
  });
}
// worker.ts
import * as Comlink from "comlink";
import { dummyTask } from "./task.js";

// Wait for 500 ms
// Modeling long-running tasks (ex. WASM compilation)
await dummyTask(500);

Comlink.expose({
  dummy: () => {
    return 42;
  },
});
// index.ts
import * as Comlink from "comlink";
import { dummyTask } from "./task.js";

const url = new URL("./worker.js", import.meta.url);

const wrapper: Comlink.Remote<{
  dummy: () => number;
}> = Comlink.wrap(new Worker(url, { type: "module" }));

// Works without problem with this line
// await dummyTask(1000);

// Never returns
const x = await wrapper.dummy();

// Unreachable
console.log(x);
eyyyyyyy3 commented 1 week ago

Yes I got the same problem. I can think of 2 workarounds:

Edit: This problem is already known #635 https://github.com/GoogleChromeLabs/comlink/issues/635#issuecomment-1590972739