Stream: wasmtime

Topic: How to use WASI with async


view this post on Zulip anb (Mar 01 2023 at 17:41):

Hi, I try to understand the way how async is implemented in wasmtime, and got some questions:

  1. How to impl async in wasm guest? From the WASI API, it looks like
    poll_oneoff is the primitive to build an event loop. If this is
    true, is there any existing crate that already implement it and
    provide async interface? I found tokio/mio seems to have limited
    support, but not sure about others.

  2. What's the difference between host side func.call_async and
    func.call in terms of use case? Assuming the function being
    called in wasm guest is going to run an event loop.

Thanks

view this post on Zulip bjorn3 (Mar 01 2023 at 19:07):

call_async allows pausing the entire wasm guest if a future isn't ready in a way transparent for the wasm guest. poll_oneoff is when the guest itself needs to do multiple async things at once.

view this post on Zulip anb (Mar 01 2023 at 19:16):

if a future isn't ready

Is the future on the guest side? How does guest yield if it got a pending future?

view this post on Zulip Lann Martin (Mar 01 2023 at 19:22):

There isn't yet a general purpose way for guests to yield. Async support for guests is planned but not yet started afaik

view this post on Zulip Lann Martin (Mar 01 2023 at 19:22):

You could build your own, but its mostly unrelated to wasmtime's async support

view this post on Zulip Lann Martin (Mar 01 2023 at 19:25):

One thing you can do with wasmtime's async is yield from a host-defined import, e.g. if you have a call stack (host) -> (guest) -> (host), that last host function can yield which will propogate all the way back to the first host function, but it all looks synchronous to the guest

view this post on Zulip anb (Mar 01 2023 at 19:46):

... will propogate all the way back to the first host function, but it all looks synchronous to the guest

I see, guess that's the purpose of those Linker::func_wrapX_async.

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:22):

the above is all correct. basically, if you configure your engine to be async, you need to use func.call_async and Linker::func_wrapX_async

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:22):

but its only asyncness in terms of allowing host code to await on futures.

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:24):

when you initialize wasi-common using the wasi-tokio crate's WasiCtxBuilder, you will get an underlying implementation of poll_oneoff that polls a set of tokio futures corresponding to the files and timeouts its waiting on

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:26):

otoh, the corresponding implementation in wasi-cap-std-sync will run std::thread::sleep() to wait on a timeout

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:26):

as well as a blocking call to poll(2) to wait on file readiness

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:28):

so, basically, if you want to use async and wasi, depend on wasmtime-wasi = { version = "whatever", default-features=false, features = ["tokio"] }

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:28):

and then use wasmtime_wasi::tokio::WasiCtxBuilder to build your wasi ctx.

view this post on Zulip Pat Hickey (Mar 01 2023 at 21:29):

of course, this isnt general to all async rust, it will panic if its not running on top of tokio.

view this post on Zulip Joel Dice (Mar 02 2023 at 02:03):

Yeah, Fortran certainly adds an interesting challenge. I have no idea what the state of the art for Fortran-to-Wasm is. Good luck! Let me know if you get stuck and need a second pair of eyes on it.

view this post on Zulip Joel Dice (Mar 02 2023 at 14:10):

Ugh, disregard the above -- wrong stream -- I'm still bad a Zulip.

view this post on Zulip Ralph (Mar 02 2023 at 15:40):

where was fortran supposed to go? because now you got me interested!!!


Last updated: Dec 23 2024 at 13:07 UTC