- Tasks
- Wakers
- Executors
- Pin
- Every async function that awaits creates tasks
- Effectively "subtasks" of the function
- Tasks describe dependencies
async fn learn_and_sing() {
let song = learn_song().await; // 1
sing_song(song).await; // 2
sing_song(song).await; // 3
}
- Functions become a state machine
- State machines can restart once progress can be made
- Similar to generators
- Polling all the tasks is a busy wait
- Wakers allow us to register a way to wake
- All types by default can move
- But what if you want to prevent it
- Pin: underlying memory can not move
#[tokio::main]
async fn main() {
let mut stream = async_stream();
let sleep = time::sleep(Duration::from_secs(10));
tokio::pin!(sleep);
loop {
tokio::select! {
maybe_v = stream.next() => {
if maybe_v.is_none() { break }
println!("got = {:?}", maybe_v);
}
_ = &mut sleep => {
println!("timeout: 10 secs elapsed");
break;
}
}
}
}
- Start with the top-level Futures and drive to completions
- Calls
wake()
when a task can make progress