How to drive a Future?

I have this toy counter which implements the Future trait:

struct AsyncCounter {
    value: u32,
    target: u32
}

impl AsyncCounter {
    fn new(target:u32) -> AsyncCounter {
        AsyncCounter {
            value: 0,
            target
        }
    }
}

impl Future for AsyncCounter {
    type Item = u32;
    type Error = u32;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if self.value == self.target {
            Ok(Async::Ready(self.value))
        } else {
            self.value += 1;
            Ok(Async::NotReady)
        }
    }
}

When I create it with a target of 0 and pass it to an executor, I get it resolved right away

However, if I create it with a target >0, it doesn't seem to update - and therefore never resolves.

From watching the first half hour or so of this video I get that there's some more machinery that needs to be hooked up from the future... like to park or notify or something so that it will get updated?

I do plan on watching the rest of that video - but it'd be nice to make some progress in the meantime :wink:

Any tips to make this simple example work?

If you return Async::NotReady from your future, the task needs to be notified in order for the executor to call poll again on the task containing your future. You can call task::current().notify() in your poll function. This case is explicitly covered in the documentation:

If the task is currently polling its future when notify is called, it must poll the future again afterwards

2 Likes

Related discussion as it applies to wasm: https://github.com/rustwasm/wasm-bindgen/issues/1126

1 Like