Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronously Wait for Message in Web-Worker

Is there some way to synchronously wait for or check for a new message in a web-worker?

I have a large complicated body of code (compiled LLVM from emscripten) that I cannot refactor around callbacks.

I need to make sure that code after a certain line doesn't execute until I receive and handle a message from the UI-thread. If I block with a while-loop, the event-loop never runs so I can't receive messages.

like image 907
bkase Avatar asked May 14 '12 20:05

bkase


1 Answers

This is an issue that I also ran into while working with Pyodide. I wanted to 'synchronously' call a function from the main thread.

One solution involves the Atomics and SharedArrayBuffer APIs. From the perspective of the web worker, this looks like the following

  1. postMessage the main thread
  2. freeze ourselves with Atomics.wait
  3. get unfrozen by the main thread
  4. read the result from a SharedArrayBuffer. We can't receive the result as a postMessage, because there isn't a synchronous way of asking "did I get a message".

Of course this requires a fair amount of extra code to handle all the serialization, data passing and more.

One limitation of this are that it won't work in Safari, because Safari does not implement the Atomics API. Another limitation is that to use those APIs, one needs to have the COOP/COEP headers set.

There is also an alternative solution with synchronous XHR and a service worker, but I haven't investigated that option.

like image 74
Stefnotch Avatar answered Sep 19 '22 13:09

Stefnotch