Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing "simplified" Future API incompatible with actual Future API #132

Open
bvibber opened this issue Apr 13, 2021 · 0 comments
Open

Comments

@bvibber
Copy link

bvibber commented Apr 13, 2021

Chapter 2 "The Future Trait" describes the Future API, but incorrectly:

The Future trait is at the center of asynchronous programming in Rust.
A Future is an asynchronous computation that can produce a value
(although that value may be empty, e.g. ()). A simplified version of the
future trait might look something like this:

trait SimpleFuture {
    type Output;
    fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;
}

Futures can be advanced by calling the poll function, which will drive
the future as far towards completion as possible. If the future completes,
it returns Poll::Ready(result). If the future is not able to complete yet, it
returns Poll::Pending and arranges for the wake() function to be called
when the Future is ready to make more progress. When wake() is called,
the executor driving the Future will call poll again so that the Future
can make more progress.

Without wake(), the executor would have no way of knowing when a
particular future could make progress, and would have to be constantly
polling every future. With wake(), the executor knows exactly which
futures are ready to be polled.

This indicates that the wake function is an essential, vital part of the Future API and points it out so you know about it and how to use it.

Then in Chapter 3 Task Wake-ups with Waker the actual API is revealed to be different:

impl Future for TimerFuture {
    type Output = ();
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {

This is actually known to the authors, as it's noted at the end of Chapter 2 that it was incorrect:

Secondly, wake: fn() has changed to &mut Context<'_>. In SimpleFuture,
we used a call to a function pointer (fn()) to tell the future executor that
the future in question should be polled. However, since fn() is just a
function pointer, it can't store any data about which Future called wake.

I think it would be much less confusing if the actual API were used instead of a false API being exposed and generalized, with a tiny note at the end that it doesn't apply in real life.

Thank you for your time and consideration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant