This topic was moved here from #general > Async component calls with exclusive locks on their stores by Till Schneidereit.
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
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
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 cannot seem to access the run_concurrent method using bindgen-generated bindings.
I am not sure how to incorporate this into my current design as
run_concurrentstill requires a mutable reference to aStore. Is there a way I can instead maybe store anAccessorin a struct which I can then just re-use? Maybe I am missing a way to make this work withrun_concurrent?
If I add the async keyword in front of host functions they all break:
Example error message: method
shutdownis not a member of traitHostFunctionsnot a member of traitHostFunctions
Generally wondering if there is some place I can find what all bindgen! config options do.
I am sorry for being all over the place before, I hope this helps to explain my issue a bit more.
I cannot seem to access the
run_concurrentmethod 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
asynckeyword 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.
- Generally wondering if there is some place I can find what all
bindgen!config options do.
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
That is a good recommendation for how I could make async component calls work with my use case!
Using
async | storeimports (whichasyncfunctions 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_concurrentmethod 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.
As in, the method doesn't exist at all on Instance? Or it doesn't exist on the generated bindings?
(it's not part of the generated bindings, it's part of Instance)
if it's not there double-check you've got the component-model-async feature enabled on the wasmtime crate
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_concurrentmethod, 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.
And also make sure the component-model-async feature is enabled like Alex said.
Joel Dice said:
run_concurrentis not generated or exposed as part of the generated bindings. Instead, it's an associated function on theInstancetype. Consequently, you need to separately create theInstanceand 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?
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.
The generated bindings for an async WIT function will use TypedFunc::call_concurrent internally.
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?
Yeah, that makes sense -- it would be a simple pass-through function, so easy to implement in the bindings generator.
Should I make a feature request issue in the wasmtime repository for tracking purposes?
Last updated: Dec 06 2025 at 06:05 UTC