async-io icon indicating copy to clipboard operation
async-io copied to clipboard

Web timer support

Open notgull opened this issue 2 years ago • 5 comments

This commit adds support for async-io on wasm32-unknown-unknown. Not all features of async-io can be ported to WASM; for instance:

  • Async<T> can't be ported over as WASM doesn't really have a reactor. WASI could eventually be supported here, but that is dependent on https://github.com/smol-rs/polling/issues/102
  • block_on() can't be ported over, as blocking isn't allowed on the web.

The only thing left is Timer, which can be implemented using setTimeout and setInterval. So that's what's been done: when the WASM target family is enabled, Async<T> and block_on() will be disabled and Timer will switch to an implementation that uses web timeouts.

This is not a breaking change, as this crate previously failed to compile on web platforms anyways.

This functionality currently does not support Node.js.

Closes #89

notgull avatar Sep 23 '23 01:09 notgull

https://github.com/smol-rs/async-io/actions/runs/6358096463/job/17270021140#step:11:44

     Running unittests src/lib.rs (target/wasm32-unknown-unknown/debug/deps/async_io-1a608e2b038c59[41](https://github.com/smol-rs/async-io/actions/runs/6358096463/job/17270021140#step:11:42).wasm)
no tests to run!
     Running tests/async.rs (target/wasm32-unknown-unknown/debug/deps/async-6cc94a735e74c985.wasm)
                                                  
no tests to run!
     Running tests/block_on.rs (target/wasm32-unknown-unknown/debug/deps/block_on-0[44](https://github.com/smol-rs/async-io/actions/runs/6358096463/job/17270021140#step:11:45)b18783949e5c2.wasm)
                                                  
no tests to run!
     Running tests/timer.rs (target/wasm32-unknown-unknown/debug/deps/timer-2[47](https://github.com/smol-rs/async-io/actions/runs/6358096463/job/17270021140#step:11:48)dda665b5d544f.wasm)
                                                  
this test suite is only configured to run in a browser, but we're only testing node.js tests so skipping

taiki-e avatar Sep 30 '23 04:09 taiki-e

This functionality currently does not support Node.js.

It probably does not work in Web Worker either. https://github.com/rustwasm/wasm-bindgen/issues/1046

Also, there may be an issue mentioned here. https://github.com/tomaka/wasm-timer/issues/21#issuecomment-1484553707 (It would make sense to mention in the documentation if such a problem exists.)

taiki-e avatar Oct 07 '23 14:10 taiki-e

The Prioritized Task Scheduling API is currently the solution to this problem, but is unfortunately only supported by Chrome so far, but Firefox is working on it.

The nested call throttling of setTimeout() and setInterval() can be circumvented by using a MessagePort (I didn't find anything better so far) to queue either.

See the Winit implementation as an example:

It probably does not work in Web Worker either.

This can be circumvented by providing your own bindings, e.g. I've done this in web-time.

daxpedda avatar Oct 07 '23 15:10 daxpedda

I would prefer having wider browser support. I'll add a note to the documentation for Timer clarifying that on web platforms it can take longer.

notgull avatar Oct 08 '23 04:10 notgull

I would prefer having wider browser support.

You can do runtime support detection, we have done this in Winit.

daxpedda avatar Oct 08 '23 06:10 daxpedda

How is this PR going?

VitalyAnkh avatar Aug 26 '25 07:08 VitalyAnkh

How is this PR going?

Probably needs a ground-up rewrite given the new architecture.

notgull avatar Aug 27 '25 01:08 notgull