Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Futures created with wasm_bindgen_futures::spawn_local don't get executed #6

Closed
felipellrocha opened this issue Jun 16, 2022 · 9 comments

Comments

@felipellrocha
Copy link

I'm spinning a thread using wasm_thread. Inside of it, I'm running some async functions inside of a wasm_bindgen_futures::spawn_local as such:

wasm_thread::spawn(move || {
  log::info!("1: spawn");
  while Ok(message) = channel_receiver.recv() {
    log::info!("2: message {:?}", &message);
    wasm_bindgen_futures::spawn_local(async move {
      log::info!("3: am i here?");
      download.asset().await;
    })
  }
});

Problem is that neither the 3rd log::info!() nor the download.asset().await get called.

Any idea why?

@chemicstry
Copy link
Owner

chemicstry commented Jun 16, 2022

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.

@chemicstry
Copy link
Owner

I think the problem here might be the channel_receiver.recv(). What kind of channel is that? Try using an async one

@felipellrocha
Copy link
Author

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

@chemicstry
Copy link
Owner

chemicstry commented Jun 16, 2022

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().

@felipellrocha
Copy link
Author

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)

@DouglasDwyer
Copy link
Contributor

@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).

@felipellrocha
Copy link
Author

This worked: rustwasm/wasm-bindgen#2945 Thanks for the help :D

@Liamolucko
Copy link

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.

@chemicstry
Copy link
Owner

Closing this and tracking async entrypoints in #10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants