I have several WebAssembly modules written in Rust using synchronous code. Here's how they're currently structured:
mod bindings;
pub use bindings::{Guest, Object, Value};
pub struct Extract;
impl Guest for Extract {
fn query(args: Vec<(String, Value)>) -> Result<Object, String> {
let result: Vec<Vec<(String, String)>> = Vec::new();
// do something
Ok(result)
}
}
bindings::export!(Extract with_types_in bindings);
Module Side: How should I modify the WASM module to support async functions?
async
before fn
and use .await
on async callsHost Side: I'm using wasmtime in Rust to call these modules. Current calling pattern:
rust
f.call(&self, mut store: impl AsContextMut, params: &[Val], results: &mut [Val])
Mixed Async/Sync Environment:
f.call_async()
and implement polling in the host?Has anyone implemented something similar or can point me in the right direction?
I have implemented an async executor for WebAssembly in the context of: https://wasmcloud.com/blog/2024-12-10-leptos-and-wasi-0.2-for-full-stack-wasm-development
Basically, my implementation makes any pollable
awaitable like that:
WasiPoll::new(your_pollable).await
So if you somehow can make your host return a pollable
, it should do but I don't know if it's something easy to do with Wasmtime. I will let expert answer on this one!
The code is there: https://github.com/leptos-rs/leptos_wasi/blob/main/src/executor.rs
I have been thinking about porting the implementation to a standalone crate as well but IDK how useful it would be
Utilize3214 said:
Has anyone implemented something similar or can point me in the right direction?
Take a look at Joel's WASI 0.3 prototype at https://github.com/dicej/component-async-demo - I believe this is the most advanced way of combining sync and async. Also Luke's talk "stream of conscious on the future of components" explains its concepts pretty well.
Here is the link to Luke's talk YouTube - - YouTube
FYI, that component-async-demo
repo is based on forks of wasm-tools
, wit-bindgen
, and wasmtime
, and the wasmtime
one in particular is not yet ready for serious use. I'm working to get all those forks merged upstream, but until that's done you should consider the code experimental. And even after everything's merged, the async parts will be gated behind a Cargo feature that's disabled by default, so you should _still_ consider it experimental until that feature is enabled by default.
Meanwhile, there are several WASIp2-compatible async runtimes/executors out there besides the one @raskyld mentioned, e.g. https://crates.io/crates/wasi-async-runtime and https://crates.io/crates/spin-executor. You could even write your own without a lot of trouble.
Last updated: Dec 23 2024 at 12:05 UTC