Stream: general

Topic: ✔ Calling async wasm functions from wasmtime


view this post on Zulip Christian Dürr (May 03 2022 at 12:37):

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.

view this post on Zulip Alex Crichton (May 03 2022 at 14:18):

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

view this post on Zulip Christian Dürr (May 03 2022 at 15:23):

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?

view this post on Zulip Alex Crichton (May 03 2022 at 15:26):

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)

view this post on Zulip Christian Dürr (May 03 2022 at 15:38):

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.

view this post on Zulip Alex Crichton (May 03 2022 at 15:45):

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

view this post on Zulip Christian Dürr (May 03 2022 at 15:52):

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?

view this post on Zulip Alex Crichton (May 03 2022 at 16:03):

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

view this post on Zulip Christian Dürr (May 03 2022 at 16:08):

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.

view this post on Zulip Alex Crichton (May 03 2022 at 16:16):

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

view this post on Zulip Alex Crichton (May 03 2022 at 16:17):

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

view this post on Zulip Alex Crichton (May 03 2022 at 16:17):

I believe this is the async flag to the Wasmtime code generator

view this post on Zulip Christian Dürr (May 03 2022 at 17:44):

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: * });

view this post on Zulip Notification Bot (May 03 2022 at 17:45):

Christian Dürr has marked this topic as resolved.


Last updated: Dec 23 2024 at 12:05 UTC