[Webkit-unassigned] [Bug 271756] Can new Worker() be made to properly operate on the background (maybe when the URL is an in-memory Blob)?
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Fri Mar 29 12:31:02 PDT 2024
https://bugs.webkit.org/show_bug.cgi?id=271756
--- Comment #5 from jujjyl at gmail.com ---
> Adding a few other folks for visibility, so that your feedback is well considered.
Thanks!
> encouraging blocking the main thread may limit what can be done to further improve.
I would stress here that this issue is not about blocking the main thread per se.
Rather, this issue is about enabling a site to allocate resources only when they are actually needed, instead of needing to (wastefully) preallocate Workers earlier.
To illustrate, already today one can write code like this:
`b.html`
```html
<html><body><script>
fetch('b.js').then(response => response.blob()).then(blob => {
let worker = new Worker(URL.createObjectURL(blob));
worker.postMessage('init');
worker.onmessage = () => {
let sab = new Uint8Array(new SharedArrayBuffer(16));
worker.postMessage(sab);
console.log('Waiting for Worker to finish');
while(sab[0] != 1) /*wait to join with the result*/;
console.log(`Worker finished. SAB: ${sab[0]}`);
};
});
</script></body></html>
```
`b.js`
```js
onmessage = (e) => {
if (e.data == 'init') {
console.log('Worker received SAB');
postMessage(0);
} else {
console.log('Received SAB');
e.data[0] = 1;
}
}
```
The above code example does not hang, but works correctly. Both a.html and b.html do block the main thread equally, in other words, the root issue at the heart of this problem is not the "blocking the main thread" part.
The workaround scheme shown by b.html is what WebAssembly/SharedArrayBuffer users use today since a.html does not work.
The difference between b.html and a.html is that in b.html, "worker.postMessage()" **is** able to make forward progress even while the main thread is spinwaiting for the worker, whereas "new Worker()" in a.html is not able to.
But the troubling affairs with the workaround presented by b.html is that in that example, one must preallocate the Worker up front. In real world programs, this must happen before the code necessarily knows if it is going to need the Worker in the first place.
For example, in https://github.com/juj/emgc I have implemented a multithreaded garbage collector, to be used in C#/Java/Python VMs compiled to multithreaded WebAssembly.
In that GC, I would like to perform the GC marking step quicker by using a pool of background Workers. But I would also like to spawn that GC marking Worker pool only on-demand when necessary, instead of requiring the whole WebAssembly site to have to delay its page startup until I first manage to spin up all the GC Workers (that may or may not even ever fire, depending on what the user does on the site!).
If the code example in a.html worked, then I would be able to only ever spawn the GC Workers synchronously at the first occassion that I need to GC, which would lead to a kind of "only-pay-if-you-use-it" type of allocation of site resources.
This is just one example. Similar needs occur in Emscripten multithreaded WebAssembly users also in other scenarios, e.g. when implementing multithreaded WebGPU rendering, or multithreaded parallel for() constructs, and similar.
So ideally, if "new Worker(inMemoryBlob)" was able to complete without needing to yield back to the main JS event loop, all of that wasteful preallocation of "new Worker()"s could be avoided, and multithreaded WebAssembly sites would not need to start up by creating an avalanche of Workers that they might only potentially need to ever use - that would be a big help to WebAssembly site startup performance overall!
--
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20240329/19d4b2e6/attachment.htm>
More information about the webkit-unassigned
mailing list