'WebAssembly blocks the web worker thread too
This is related to the previous question WebAssembly in async code
Basically, that question is about the problem of the WebAssembly blocking the main thread, and the answer to the question is to move the WebAssembly code to a web worker. That works.
The problem now is that the WebAssembly blocks the onmessage() on the worker.
My long running WebAssembly code has functions like play(), pause(), stop(), etc. The play() checks a pause flag and a stop flag periodically to determine if the play() should return. The pause() and the stop() are used to set those flags.
The JavaScript main thread calls postMessage() to send a message to the worker, which further calls the play().
Since the onmessage() is blocked, the worker will have no chance to receive further messages to do pause() or stop() until the play() is completed. That will defeat the very purposes of the pause/stop.
It seems the simple use case of play/pause/stop cannot be supported by the WebAssembly.
Any comments or suggestions?
By the way, that use case is well supported by the defunct Google PNaCl.
Thanks.
Solution 1:[1]
In short: Web worksers do not ignore messages even if the web worker thread is blocked.
All browsers events, including web worker postMessage()
/onmessage()
events are queued. This is the fundamental philosophy of JavaScript (onmessage()
is done in JS even if you use WebAssembly). Have a look at "Concurrency model and Event Loop" from MDN for further detail.
So what going to happen in your case is, while onmessage()
is blocked, the events from main thread postMessage()
are queued automatically. When a single onmessage()
job is finished in the worker thread, from the worker event queue, will check if postMessage()
is called before it finishes and catch the message if there is. So you don't need to worry about that case as long as the onmessage()
job takes like 10 seconds and the you get hundreds of events in the queue.
This is how asynchronous execution is done everywhere in the browser.
Solution 2:[2]
Considering you are targeting recent browsers (WebAssembly), you can most likely rely on SharedArrayBuffer and Atomics. Have a look at these solutions Is it possible to pause/resume a web worker externally? , which in your case will need to be handled inside WebAssembly (Atomics.wait
part)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Yoz |