Stream: git-wasmtime

Topic: wasmtime / issue #12991 c-api: wasmtime_call_future_poll ...


view this post on Zulip Wasmtime GitHub notifications bot (Apr 08 2026 at 19:39):

chaynabors opened issue #12991:

In referencing the module-level async implementation for #12973, I didn't think to wire up a waker. wasmtime_call_future_poll passes Waker::noop() when polling the underlying Rust future, so there's no way for the caller to know when the future is ready to make progress.

For our use case this is worth adding. We're hosting components from Python via wasmtime-py and need to integrate with asyncio's event loop. Without a waker, the only option is busy-polling with asyncio.sleep(0), which wastes CPU and adds latency. The same problem would apply to any language binding that integrates with a cooperative event loop.

Adding a nullable waker parameter to the existing wasmtime_call_future_poll (NULL = Waker::noop(), same behavior as today) would be an ABI break but not a behavioral one. There's no performance advantage to omitting the waker since even tight poll loops would just pass NULL. A new function like wasmtime_call_future_poll_with_waker would avoid the ABI break entirely.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 08 2026 at 19:41):

chaynabors commented on issue #12991:

Happy to implement if a maintainer has an opinion on the API surface.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 08 2026 at 19:53):

chaynabors edited issue #12991:

In referencing the module-level async implementation for #12973, I matched the existing behavior for the waker. wasmtime_call_future_poll passes Waker::noop() when polling the underlying Rust future, so there's no way for the caller to know when the future is ready to make progress.

For our use case this is worth adding. We're hosting components from Python via wasmtime-py and need to integrate with asyncio's event loop. Without a waker, the only option is busy-polling with asyncio.sleep(0). The same problem would apply to any language binding that integrates with a cooperative event loop.

Adding a nullable waker parameter to the existing wasmtime_call_future_poll (NULL = Waker::noop(), same behavior as today) would be an ABI break but not a behavioral one. There's no meaningful performance advantage to omitting the waker as tight polling loops would simply pass NULL. A new function like wasmtime_call_future_poll_with_waker would avoid the ABI break entirely.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 08 2026 at 19:55):

chaynabors edited a comment on issue #12991:

Happy to implement if a maintainer has an opinion on the API surface. Also team has been very helpful in getting things merged. Let me know if there's any ways for me to give back as I continue to write for my own use cases.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 08 2026 at 20:46):

chaynabors edited a comment on issue #12991:

Happy to implement if a maintainer has an opinion on the API surface.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 09 2026 at 16:52):

fitzgen assigned pchickey to issue #12991.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 10 2026 at 20:35):

alexcrichton commented on issue #12991:

Hm on second though, thinking about #12973 some more, that's the first time that Rust-host async functions are being exposed (e.g. wasmtime-wasi and wasmtime-wasi-http). Prior to #12973 the rough idea for embedders using async is they get to figure out when to call poll again as the only async parts are the embedder's own functions. With #12973, however, notably Tokio is now in the mix since that's the underlying implementation primitive of #12973. Given that I'm not actually sure how we can get this working, and I don't think it's as simple as just hooking up the waker.

For example the async APIs right now don't engage Tokio at all and I think that they might just panic if invoked at this time since Tokio isn't configured. Even if Tokio were configured part of the waker process would somehow have to involve running arbitrary Rust code to poll the Tokio event loop and move that forward...

Overall I'm not actually sure how this can work, and I'm thinking we may want to remove the bindings to async wasi/wasi-http functionality since I think it'll otherwise not work?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 10 2026 at 20:35):

alexcrichton added the wasmtime:c-api label to Issue #12991.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 11 2026 at 04:32):

chaynabors commented on issue #12991:

That all makes sense to me. A colleague tells me the component model async is working as written but that shouldn't be the case if nothing is driving the tokio machinery. Let me see what he's done in his branch on Monday. Please revert #12973 if you think that's in the interest of the project. I'd be happy to contribute something more narrow at a later date.

I assume we can model any of tokio's internals across the c-api, but my gut instinct is that the right way to do something like this is to tie it to p3. You'd know better than me. Something has to drive the executor at the spec level no? Apologies as I'm still trying to get a grip on everything.

Some quick background:

  1. We're a small team with good visibility at AWS. The team made the mistake of vending multiple identical SDK's in various languages and I'm trying to help them deduplicate them. I vetoed using JSII in favor of WASM.
  2. I'm meeting with the folks who represent us to start a working group while pushing to renew Amazon's membership in Bytecode Alliance for another year.
  3. The two changes I made to the C API and some solution to this issue are the last things we need for production.

You can reach me at nabochay at amazon.com if needed.


Last updated: Apr 12 2026 at 23:10 UTC