Closed felipellrocha closed 2 years ago
Could you be blocking browser's main thread event loop? In order for worker to spawn you either have to return from js->rust call or await on async function, so it allows browser event loop to continue.
To be more clear: busy looping in wasm main thread freezes the browser event loop. This means that no DOM events, network fetches or worker spawning can proceed. The already spawned workers should work fine though, unless they try to communicate with the main thread.
I think the problem here might be the channel_receiver.recv()
. What kind of channel is that? Try using an async one
It's a crossbeam channel. This is on a spawned thread, so it shouldn't impact the main thread no? Also, this code worked fine previously in the main thread. In addition, the documentation on spawn_local
leads me to believe the async I spawned would run in the spawned thread, not the main thread: https://docs.rs/wasm-bindgen-futures/0.4.31/wasm_bindgen_futures/fn.spawn_local.html
I might not have explained it well, but what I said also applies to the worker event loop. At least I think so, I haven't used wasm for a while now, so don't remember all the quirks.
The docs for spawn_local
say The future will always be run on the next microtask tick
. However, the worker can never execute next microtask tick because it is blocked on crossbeam channel recv()
.
I have modified it to this:
wasm_thread::spawn(move || {
log::info!("1: spawn");
wasm_bindgen_futures::spawn_local(async move {
log::info!("2: message {:?}", &message);
while Ok(message) = channel_receiver.recv().await {
log::info!("3: am i here?");
download.asset().await;
}
})
});
I still get nothing (now a tokio channel)
@felipellrocha, I am unable to reproduce your issue with the following code:
wasm_thread::spawn(move || {
log::info!("1: spawn");
wasm_bindgen_futures::spawn_local(async move {
log::info!("2: message {:?}", "hello");
})
});
The code produces both log messages. As such, this looks like it may be an issue with the channel implementation or event loop rather than an incompatibility in wasm_thread
and wasm_bindgen_futures
. I would try using a channel implementation that is independent of runtime (like async_channel
), as Tokio channels might depend upon a Tokio runtime to work (which is impossible on WASM).
This worked: https://github.com/rustwasm/wasm-bindgen/issues/2945 Thanks for the help :D
For the record, that is quite a hacky solution; I think it'd be better if wasm_thread
were to support async entrypoints, since there isn't currently any way to yield from the blocking entrypoint without shutting down the worker.
Closing this and tracking async entrypoints in #10
I'm spinning a thread using
wasm_thread
. Inside of it, I'm running some async functions inside of awasm_bindgen_futures::spawn_local
as such:Problem is that neither the 3rd
log::info!()
nor thedownload.asset().await
get called.Any idea why?