Stream: general

Topic: Pollable in tokio


view this post on Zulip Joel (Oct 19 2025 at 12:43):

Hello, I have a problem with Pollable in wasmtime.

I have:

#[async_trait]
impl Pollable for MyResource{
  async ready(&mut self){
    eprintln("ready - 1");
    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
    eprintln("ready - 2");
  }
}

The sleep timer never clicks. I only see "ready - 1" in the logs. I never see "ready - 2". Is this because I call Ready() before Block() inside my wasm guest?

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:13):

so just to set the table there are two different readys: pollable.ready the wit method, and async fn Pollable::ready(&mut self) the Rust method

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:15):

pollable.block is equivalent to Pollable::ready(&mut pollable_resource).await. pollable.ready is equivalent to futures::future::[poll_immediate](https://docs.rs/futures/latest/futures/future/fn.poll_immediate.html)(async { Pollable::ready(&mut pollable_resource).await }).await- basically it creates the future returned by the Pollable::ready method, and then it calls Future::poll on it exactly once, and returns true if it was Poll::Ready and false if it was Poll::Pending

view this post on Zulip Joel (Oct 19 2025 at 21:16):

Hi. I am trying to implement the pollable.ready WIT method in the host. So I implemented Pollable::read(&mut self).

I notice that if I add a panic after "read - 2" log line, that the future gets "read".

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:16):

yeah, thats intended

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:16):

whats going on there is that async {} block is changed by rustc to a Future

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:17):

the async block contains your eprintln!(1), then a function that will be Pending for 3 seconds and finally Ready, then eprintln!(2)

view this post on Zulip Joel (Oct 19 2025 at 21:17):

But without the panic, the 3 second timer never lapses for me.

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:17):

correct, the panic is just the symptom

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:18):

what are you trying to achieve here

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:18):

theres a disconnect between your understanding of rust Futures and my docs and description of this interface, the differences are indeed subtle

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:19):

the goal of async fn Pollable::ready is that it becomes ready when the pollable is ready, but the method itself can be called a number of times (in calls to pollable.ready which is a nonblocking check, in calls to pollable.block, and in calls to poll.poll)

view this post on Zulip Joel (Oct 19 2025 at 21:19):

I am trying to write a ready function using tokio async (ie a normal async function). And my wasm guest calls Block(). I expect the host-side ready function to resolve after the timer elapses and the guest to unblock.

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:20):

so if you write an implementation of Pollable::ready that cant handle it being created and canceled arbitrarily you will not get what you want

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:20):

tell me more about what a normal async function is in your context.

view this post on Zulip Joel (Oct 19 2025 at 21:21):

I have a flume channel I want to read from. But, I cannot even get a simple tokio timer to work.

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:26):

so, if you want to implement a pollable for something that is only ready 3 seconds after creation, you need to write the resource as storing the Instant at which it is ready, and impl Pollable with tokio::time::sleep_until(self.instant).await, see https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasi/src/p2/host/clocks.rs#L124

A lightweight WebAssembly runtime that is fast, secure, and standards-compliant - bytecodealliance/wasmtime

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:27):

because theres a difference between the creation of the resource itself, and the lifetime of the future given by the Pollable::ready function.

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:27):

theres a lot going on in there because of the way wasi works

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:28):

you'll have to read the source code of that clocks impl in wasmtime-wasi p2 and also the wasmtime-wasi-io implementation of pollable if you want to fully internalize it

view this post on Zulip Joel (Oct 19 2025 at 21:29):

Thanks, I will take another crack at this focusing on the clock and wasi-io example.

view this post on Zulip Joel (Oct 19 2025 at 21:29):

I am guessing the future canceling part is what I am missing, but I need to do more research to understand.

view this post on Zulip Pat Hickey (Oct 19 2025 at 21:29):

you could also write your resource to contain a MaybeDone(your-fut) https://docs.rs/futures/latest/futures/future/enum.MaybeDone.html and then Pollable can await the MaybeDone, and when youre trying to add another method to the resource to get a thing out of your flume channel, you can use MaybeDone::output_mut to pop something out of the inside.

view this post on Zulip Joel (Oct 19 2025 at 21:30):

Ah, this looks easier for me.

view this post on Zulip Joel (Oct 19 2025 at 21:54):

I tried using a simple tokio::time::sleep_until(*instant).await just like the Clock example, but to no avail. I am not sure how to use MaybeDone in the Pollable implementation.

I tried defining an async block on every invocation of the ready function, then doing an await on the result. However, that did not work either.

view this post on Zulip Joel (Oct 20 2025 at 00:56):

Thanks. I appreciate the help, but there must be something else going on with my setup as the future is not being read. I tried your suggestion, but the timer never goes off.

I can't really understand why by putting a panic in a future the future is evaluated, but if I don't put a panic the future is never evaluated. So, I will do research on that.

view this post on Zulip Joel (Oct 20 2025 at 01:17):

Ok, so, it looks like if I make multiple Ready calls from the wasm guest, all the Pollable futures get blocked. If I just do one call at a time from the guest, I don't get blocks. This is similar to what someone told me in a previous question I asked on this forum, but I assumed that was for Block calls and not Ready calls.


Last updated: Dec 06 2025 at 05:03 UTC