Stream: wasmtime

Topic: Async component calls with exclusive locks on their stores


view this post on Zulip Notification Bot (Sep 29 2025 at 10:35):

This topic was moved here from #general > Async component calls with exclusive locks on their stores by Till Schneidereit.

view this post on Zulip Joel Dice (Sep 29 2025 at 14:00):

Here's an example of using Instance::run_concurrent to start several concurrent calls to the guest and then join them all, in case it's useful: https://github.com/bytecodealliance/wasmtime/blob/df21758b250366717d56ae9b972860de4e3d71bd/crates/misc/component-async-tests/tests/scenario/round_trip.rs#L197-L270. The bindings for that test are generated here

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime
A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Alex Crichton (Sep 29 2025 at 14:16):

Would you be able to post a gist of something that doesn't compile perhaps? I'm not quite following the various permutations that have been attempted here myself. Changing bindings behavior can radically change how you're supposed to use the generated APIs so it's not minor knobs to tune but moreso architectural foundations to change

view this post on Zulip Celarye (Sep 29 2025 at 15:09):

This comes from a project which I am currently rewriting and is a bit all over the place (doesn't even compile right now :sweat_smile:). But if it helps, my whole wasmtime implementation currently lives in runtime.rs. This repository also includes my WIT files in its wit directory.

To repeat the current issues I am experiencing:

I am sorry for being all over the place before, I hope this helps to explain my issue a bit more.

A WASI plugin based Discord bot, configurable through YAML. - celarye/discord-bot
A WASI plugin based Discord bot, configurable through YAML. - celarye/discord-bot

view this post on Zulip Alex Crichton (Sep 29 2025 at 19:14):

I cannot seem to access the run_concurrent method using bindgen-generated bindings.

For this you're right you need a mutable reference to start, but the way it's intended to be used is that you start with a mutable reference and then internally within the closure you do all the async bits you could want. That would require you to structure the application to have concurrent bits within run_concurrent, although I'm not sure how feasible that would be for your use case. An example of this would be that call_scheduled_job would, for example, take &Accessor as an argument. Alternatively if that weren't possible you could have a spawned tokio task which runs wasm and you communicate with that task via channels. That task would basically sit inside of run_concurrent listening on a channel and could coordinate work internally.

If I add the async keyword in front of host functions they all break:

Using async | store imports (which async functions in WIT default to) changes the shape of bindings generated. You can find a bit of documentation about that here.

I'd recommend this documentation or this documentation. If something is missing though feel free to file an issue! p3 stuff is pretty new so may not be fully integrated yet

view this post on Zulip Celarye (Sep 29 2025 at 19:41):

That is a good recommendation for how I could make async component calls work with my use case!

Using async | store imports (which async functions in WIT default to)

Ah I see, that explains the previous behavior I was seeing.

Thanks for the linked options reference and examples, I will take a detailed look at them to try and understand bindgen! a bit better (as atm I don't really know what adding store to import or export does :man_facepalming:).

Before I send:

I cannot seem to access the run_concurrent method using bindgen-generated bindings.

I am actually still not sure what I am doing wrong with that? The linked example async instantiate a component and then have a .run_concurrent method, which I do not for some reason. I'll take another look to see if I can find what I am missing though.

view this post on Zulip Alex Crichton (Sep 29 2025 at 19:45):

As in, the method doesn't exist at all on Instance? Or it doesn't exist on the generated bindings?

view this post on Zulip Alex Crichton (Sep 29 2025 at 19:45):

(it's not part of the generated bindings, it's part of Instance)

view this post on Zulip Alex Crichton (Sep 29 2025 at 19:45):

if it's not there double-check you've got the component-model-async feature enabled on the wasmtime crate

view this post on Zulip Joel Dice (Sep 29 2025 at 19:46):

Celarye said:

I am actually still not sure what I am doing wrong with that? The linked example async instantiate a component and then have a .run_concurrent method, which I do not for some reason. I'll take another look to see if I can find what I am missing though.

run_concurrent is not generated or exposed as part of the generated bindings. Instead, it's an associated function on the Instance type. Consequently, you need to separately create the Instance and wrap it in the generated bindings so you can use it both directly and via the generated bindings. See here in the example.

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Joel Dice (Sep 29 2025 at 19:47):

And also make sure the component-model-async feature is enabled like Alex said.

view this post on Zulip Celarye (Sep 29 2025 at 20:44):

Joel Dice said:

run_concurrent is not generated or exposed as part of the generated bindings. Instead, it's an associated function on the Instance type. Consequently, you need to separately create the Instance and wrap it in the generated bindings so you can use it both directly and via the generated bindings.

I see, and I assume I would then want to also combine this with Func::call_concurrent, removing the need for a bindings generated instance? Is it planned for generated bindings to eventually gain support for this functionality as well?

view this post on Zulip Joel Dice (Sep 29 2025 at 20:50):

You could use it with Func::call_concurrent, but you could just as easily use it with the generated bindings as well, as is done here.

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Joel Dice (Sep 29 2025 at 20:52):

The generated bindings for an async WIT function will use TypedFunc::call_concurrent internally.

view this post on Zulip Celarye (Sep 29 2025 at 21:06):

From my standpoint (not knowing how and why things work under the hood) it would then be nice to have run_concurrent accessible from your generated bindings as well instead of having to create a separate Instance of the same component alongside your bindgen generated one?

view this post on Zulip Joel Dice (Sep 29 2025 at 21:31):

Yeah, that makes sense -- it would be a simple pass-through function, so easy to implement in the bindings generator.

view this post on Zulip Celarye (Sep 29 2025 at 21:34):

Should I make a feature request issue in the wasmtime repository for tracking purposes?


Last updated: Dec 06 2025 at 06:05 UTC