I've been playing around with wasmtime and wit-bindgen a bit, trying to get into some more "advanced" usecases of wasm with memory and async.
From what I was able to tell, using .wit files is currently the recommended way to pass things like Vec
between host and wasm, which works fine for me so far.
However it seems like exporting an async function from wasm
doesn't work by default. I've enabled async_support
in my wasmtime config, but I still get canonical_abi::async_export_done has not been defined
as an error when trying to execute it.
Is wit_bindgen_rust::export!("../_.wit");
and then #[wit_bindgen_rust::async_trait(?Send)]
on the trait the recommended way to export async functions from WASM? If so, do I have to manually export the async_export_done
function or should wasmtime
do that for me if I configure it correctly?
Edit: I'm using Rust both sides.
The async story of wit-bindgen is in general very underbaked and as you're finding buggy. It's got various ideas but none of them were ever 100% fleshed out and finished, so I don't think it's in a workable state where it can be used off-the-shelf
Is there any reasonable way to make it work at all? Or would I just be wasting my time trying to look into that?
Not being able to export async functions in wasm modules at all seems like an unfortunate restriction, especially because it looks like it should (almost) work?
Sorry aside from diving into the code I don't have much to offer. The implemented version of async is pretty far off from what it's expected the component model will land on, so the support already in there may be able to be easily tweaked to get to a workable state but it's not going to the final state of async (and will eventually be removed in favor of something else)
Thanks for the advice. I'd assume you're not aware of any existing projects making use of async functions exported by wasm? Otherwise I'd love to dive into their code a bit.
I'll probably have to tinker around with it a bit anyway, getting async to work would probably be really nice but I might be able to live without.
I know of projects using Wasmtime's async support, but that's distinct from the async support this is building. The async support in wit-bindgen for wasm itself I'm not aware of anyone using
Does wasmtime's async support make it possible to call functions that are defined as async
in the wasm module itself? I've defined async host functions to be called as async from wasm, and I know there's a bunch of call_async
functions which should allow it. But I'm not sure it's actually possible?
Like if it's possible to do it just with wasmtime itself, I don't need to use wit-bindgen?
no wasmtime's async support allows the wasm module to pretend the world is blocking, so wasm itself gets no access to async
features (e.g. call two imports concurrently). To Wasmtime, though, host functions can be async
and while the function hasn't finished the wasm module is suspended, meaning the host can do other things.
Basically it's a model that allows the host to be async when the host functions are async, but to wasm everything still appears blocking
Oh, thanks for the explanation. That actually sheds some light on how my previous usages of the wasmtime async feature actually worked.
That said, this might still be useful for defining async API calls in the host and just using them as blocking functions in wasm, which is my main usecase anyway.
Ah yes if your use case is simply making the host's async functions work in the guest (and the guest thinks they're all blocking), then I'd recommend the async support in Wasmtime over what wit-bindgen has
wit-bindgen also has support for this flavor of async where content has no support to async features (it's all blocking) but the host does async stuff, I think the flags are probably pretty confusing
I believe this is the async
flag to the Wasmtime code generator
Yeah, I just figured this out after reading through the proc macro myself. So for anyone wondering, this will allow you to use async in your host functions in functions generated as blocking in the *.wit file (same works for imports):
wit_bindgen_wasmtime::export!({ paths: ["../interface.wit"], async: * });
Christian Dürr has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC