I am using wasmtime 13.0 (git) and wasi to facilitate game code scripting in a game engine.
The wasi api is built on an async: true
wit import and async traits. Is it possible to opt in to a blocking mode for the guest an host code calls rather than having to await the guest code function calls etc?
I see that there has been some recent activity on github with the sync feature and wasi-cap-std-sync
etc which implement a blocking non async-trait version of wasi. I could unfortunately not entirely grasp the relevant commits or how to properly use it as when testing it still bound using the preview2::bindings::filesystem::preopens::add_to_linker
etc which are async, and thus panics.
There is a possibility that I may have misunderstood something of how to use it.
@Karel Hrkal (kajacx) has investigated this previously, so they may have deeper feedback
from what I remember, wasmtime internally uses tokio and a lot of async code and there's no way around that but the async: false version is solving some of the issues
basically you can have some interfaces sync but wasmtime needs a tokio runtime to run and you need some async code and bridging (channels etc) code to talk to it
Decided to open as a new topic, rather than the #wasmtime > ✔ (Host)InputStream/OutputStream async -> sync
I also figured out that tooltips don't workn the browser, but on the desktop the icons have a tooltip, so now no more misclicks :blush:
Thats no problem :smiling_face: , we are in a tokio context, but inside a blocking update/tick loop, so would prefer if the api would be sync.
Using the sync
feature, and the async: false
for my bindings still cause wasi to use async: true
for its bindings and panic as is uses the func_wrap_async
function.
thread 'tokio-runtime-worker' panicked at 'cannot use `func_wrap_async` without enabling async support in the config', /Users/
teiroberts/.cargo/git/checkouts/wasmtime-41807828cb3a7a7e/770c5d0/crates/wasmtime/src/component/linker.rs:307:9
Since you mentioned that @Karel Hrkal (kajacx) has looked into this throughly it is worthwhile to mention that I am trying to use their wasm-bridge to also support integrating with wasm modules in the browser for scripting on non-native targets, which has a blocking api
iirc there are sync versions of the bindings under e.g. preview2::bindings::sync_io::*
, but I have not personally worked with them
Yes sync versions of everything is intended to be available, for example this is running a command and this is adding imports to a Linker
. You can also browse the tests here which have more examples of running things as sync instead of async
the source implementation of everything is async
to handle the requirements of the WASI specification itself, but at a top-level it's intended that everything additionally has a sync interface
if wasmtime is executed as part of a tokio "tick" (e.g. a poll
to some other future) then there may be slight issues with that as tokio will think we're blocking within a poll
which it may not like, but if that happens let us know and we can try to figure something out
Ok, then I understand how all of that flows together. Thanks Alex.
I have managed to get sync wasi components working with command::sync::add_to_linker
, full code here
The sync methods don't work when called from an async tokio task, however. That gives an error "cannot create a new runtime inside an existing runtime", or something like that. At least that was when I was using a git dependency before, maybe it is fixed somehow now.
Ah ok yeah I was wondering if an error like that would show up. I'm not familiar enough with tokio itself to know how to fix that off the top of my head though.
If you're already executing within tokio though is it possible to execute wasm asynchronously?
yep those methods are designed only to be used outside of tokio rn. if you are running inside tokio, use command::add_to_linker and the async wasmtime Config and methods.
Would it be possible to reuse a tokio runtime rather than creating a new one?
The issue I am having is that we can't use async functions because we are inside a normal for_each in a tick and thus would prefer to block rather than have an async event loop update.
However, that loop happens to be called from within an entered (but not block_on
tokio context) so that we can use tokio::spawn
etc
I think you can spawn into a runtime without being in the runtime context via a Handle
(which would still mean having two separate runtimes)
I believe we're already using the preexisting runtime but I think the issue is a block_on
as part of a poll
which tokio doesn't like (or at least that's what I think is the issue, I could be wrong)
Last updated: Dec 23 2024 at 13:07 UTC