Moving computation to a Worker preserves UI responsiveness, but it does not make CPU or memory free. The main thread and worker exchange messages; transfers can move ownership of an ArrayBuffer, while ordinary structured cloning may copy data. A job contract needs an identity, input limit, progress rule, cancellation behavior, and output version. A worker still running an old request can return after a newer selection, so the editor must reject stale results rather than replacing the current scan.
Wasm Worker Jobs, Cancellation, and Result Order
Working case
A reviewer starts extraction on scan 29, then selects scan 47 before the first job finishes. The editor increments its job generation and tells the worker to cancel the old task. The module cannot interrupt an already-running synchronous export, so the UI also ignores any response tagged with the old generation. Only scan 47 may update the visible result. When the reviewer leaves the page, the controller terminates an unresponsive worker and releases the associated buffer instead of leaving CPU work alive in a hidden tab.
Implementation boundary
function acceptWorkerResult(currentGeneration, resultGeneration) {
return currentGeneration === resultGeneration;
}
console.log(acceptWorkerResult(47, 29));
// Output: falseCreate a small worker pool only after observing throughput needs; one worker is often sufficient for a single editor. Give each job a stable ID and generation, then cap queue depth and input size. Prefer transferable buffers when the sender no longer needs the bytes, and never read a transferred buffer afterward. Support cooperative cancellation between chunks; for non-interruptible native calls, reject stale output and terminate the worker only when that cost is acceptable. Carry errors back as structured codes without private payloads. Keep DOM and media permission work on the main thread.
Cost and boundaries
Posting a large clone can add O(n) copying and peak memory. A transfer avoids that copy but changes who owns the buffer. A pool of four workers can quadruple memory pressure while competing for the same device cores. Progress messages also cost scheduling and can flood rendering if emitted for every tile. Measure input-to-result latency, long tasks on the main thread, worker startup, queue wait, cancellation delay, and peak memory. Browser scheduling can vary when a tab is backgrounded.
Failure trace
The reviewer sees scan 29 analysis over scan 47 because an old result arrived last. Add a generation check at the UI reducer. Another implementation transfers the only source buffer, then tries to create a preview from the detached sender-side bytes. Test rapid file changes, two queued jobs, termination during allocation, a background tab, a worker crash, stale progress messages, and a retry after cancellation. Confirm errors do not serialize the selected document into telemetry.
Verification
- Older jobs cannot overwrite a newer selection.
- Buffers have one sender or receiver owner after transfer.
- Worker failure leaves the editor recoverable.
Practice drill
Start two jobs in reverse completion order and prove the latest selection wins. Transfer a buffer, then assert the sending owner no longer uses it. Cap queue depth at two; the third request should replace or reject work according to the product rule. Force the worker to hang and terminate it while keeping the editable form available. Measure a low-powered device with one worker and with multiple workers before choosing concurrency.
Decision note
Use a worker for responsiveness, then define ownership and stale-result rules separately from compute correctness.
Common Mistakes
- Assuming cancellation interrupts a synchronous export.
- Starting one worker per tile without a memory budget.
- Cloning a large buffer and measuring only module time.
Connected lessons
Build Project: bounded local scan analysis and review Web Development: browser compute and peer sessions quiz; follow WebAssembly and Browser Compute; Wasm Loading, Artifact, and Fallback Contract; Wasm Linear Memory, Ownership, and Copy Cost; Wasm Capabilities, Isolation, and Performance Budget; Cooperative Main-Thread Scheduling; Asynchronous Field Validation Races.
