Async
In async Rust, the execution of asynchronous tasks is driven by the Future
trait, which is at the core of Rust's async model. Hereβs a complete and corrected explanation:
The Future
Trait
The Future
trait represents a computation that might not have completed yet but will produce a value at some point. It is defined as:
trait Future {
type Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}
How poll
Works
- The poll method is the key mechanism in Rust's async system.
- It is not called automatically; instead, an executor calls it.
poll
takes a pinned mutable reference (Pin<&mut Self>
) to the future.- It also takes a context (
&mut Context<'_>
), which provides a way to register wakers.
Return Values of poll
poll
returns a Poll<T>
, which can be:
1. Poll::Pending
β The future is not ready yet, but the executor should call poll
again later.
2. Poll::Ready(output)
β The future is done, and it returns the computed value.
Who Calls poll
?
- Futures do not start automatically when created.
- They are lazy, meaning
poll
is only called when: - The future is awaited.
- The future is polled manually by an executor.
Wakers and Context
When a future returns Poll::Pending
, it must register a waker inside Context
. The waker tells the executor when the future is ready to be polled again.
How async
Functions Work
When you write an async fn
, the Rust compiler:
1. Transforms it into a state machine that implements Future
.
2. Calls poll
whenever needed until completion.
Example: Implementing a Custom Future
Hereβs a simple example of implementing a manual Future:
use std::{
pin::Pin,
task::{Context, Poll},
time::Instant,
};
use tokio::time::sleep;
use std::future::Future;
struct Delay {
when: Instant,
}
impl Future for Delay {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if Instant::now() >= self.when {
Poll::Ready(())
} else {
cx.waker().wake_by_ref(); // Re-schedule the future
Poll::Pending
}
}
}
Summary
Future
is a trait with apoll
method.poll
is called by the executor, not automatically.- It returns
Poll::Pending
(if not done) orPoll::Ready(value)
. - If
Pending
, a waker must be registered to resume execution later. async
functions are state machines that implementFuture
automatically.
Let me know if you want a deeper breakdown of any part! π