Hello,
I'm trying to understand if it's possible to suspend a running Wasm module mid-function call and restore it at a later time.
Consider a Wasm module that exports a function wasm_main
, which in turn calls a host function host_start_job
. This host function might return an immediate result or run for days, and the host worker might be restarted during that time. The module in question doesn't have any state in linear memory but might have some global state that it can pass to host_start_job
for temporary storage.
I'm wondering if there's any option with Wasmtime (or in any other runtime for that matter) to store the current Wasm module execution stack (e.g., in a database) if the host_start_job
call doesn't complete immediately, and then reinitialize the module later (possibly in a different worker), continuing the execution of the module as if the function completed synchronously, transparently to the guest module?
For example, with the JavaScript-Promise Integration Proposal, it's possible in browsers to suspend Wasm module execution for an (almost) indefinite amount of time. However, it's not possible to store that state, and it's unclear how to restore a call stack that includes calls from the host. I'm new to Wasm, so there might be a known approach to this problem that I'm unaware of.
One option I see is to split wasm_main
into several steps: wasm_main_step1
would call host_start_job
and complete, and another wasm_main_step2
would be called with the result from the host later, potentially using a new module instance. The problem with this approach is that it considerably complicates the guest implementation, especially when the call chain includes several calls to such async result functions. Also the host that initially called wasm_main_step1
would have to support a some sort of a deferred result - ideally it would be something like a promise but there is no Wasm concept like this I know of.
Another option is using Asyncify
, though it appears to be deprecated, and I couldn't make it work for modules generated by Kotlin (it fails with an internal error). I've also seen unresolved GitHub issues in multiple repos related to Asyncify
crashes, so it's probably not a production-grade solution. It's also unclear to me what happens to the initial host call that started the call chain when Asyncify
suspends the execution.
I would appreciate any pointers on how to approach this problem or alternative solutions I might have overlooked.
Thank you for your help!
Currently, no, Wasmtime has no means of saving suspended state on the stack. Wasmtime's async support at this time looks roughly like what JSPI is for the web, and it's not possible to serialize futures to memory or similar. IIRC there's an issue or two in our repo about this but I don't have them on-hand
Thank you
IIRC there's an issue or two in our repo about this but I don't have them on-hand
This one probably https://github.com/bytecodealliance/wasmtime/issues/4002
Maybe you can suggest some direction to look at on how to approach this? It feels like this might be a common problem but surprisingly I can't find any discussions around it.
We haven't written things up in an issue, but if you search Zulip for "suspend" you'll find related topics such as:
#wasmtime > Serialize suspended fiber
#wasmtime > ✔ Suspend runtime instance
Last updated: Feb 27 2025 at 23:03 UTC