Stream: wasmtime

Topic: sync/blocking wasi api


view this post on Zulip Freja Roberts (Aug 23 2023 at 13:16):

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.

view this post on Zulip Ramon Klass (Aug 23 2023 at 13:21):

@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

view this post on Zulip Freja Roberts (Aug 23 2023 at 13:22):

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:

view this post on Zulip Freja Roberts (Aug 23 2023 at 13:26):

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

view this post on Zulip Freja Roberts (Aug 23 2023 at 13:28):

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

view this post on Zulip Lann Martin (Aug 23 2023 at 13:43):

iirc there are sync versions of the bindings under e.g. preview2::bindings::sync_io::*, but I have not personally worked with them

view this post on Zulip Alex Crichton (Aug 23 2023 at 14:16):

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

view this post on Zulip Alex Crichton (Aug 23 2023 at 14:16):

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

view this post on Zulip Alex Crichton (Aug 23 2023 at 14:17):

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

view this post on Zulip Freja Roberts (Aug 23 2023 at 15:47):

Ok, then I understand how all of that flows together. Thanks Alex.

view this post on Zulip Karel Hrkal (kajacx) (Aug 23 2023 at 18:22):

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.

view this post on Zulip Alex Crichton (Aug 23 2023 at 18:26):

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?

view this post on Zulip Pat Hickey (Aug 23 2023 at 21:42):

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.

view this post on Zulip Freja Roberts (Aug 24 2023 at 12:29):

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

view this post on Zulip Lann Martin (Aug 24 2023 at 12:46):

I think you can spawn into a runtime without being in the runtime context via a Handle

view this post on Zulip Lann Martin (Aug 24 2023 at 12:47):

(which would still mean having two separate runtimes)

view this post on Zulip Alex Crichton (Aug 24 2023 at 16:55):

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: Oct 23 2024 at 20:03 UTC