In Chapter 5, we covered one of the most popular ways of modeling concurrency in a programming language: fibers/green threads. Fibers/green threads are an example of stackful coroutines. The other popular way of modeling asynchronous program flow is by using what we call stackless coroutines, and combining Rust’s futures with async/await is an example of that. We will cover this in detail in the next chapters.
This first chapter will introduce Rust’s futures to you, and the main goals of this chapter are to do the following:
- Give you a high-level introduction to concurrency in Rust
- Explain what Rust provides and not in the language and standard library when working with async code
- Get to know why we need a runtime library in Rust
- Understand the difference between a leaf future and a non-leaf future
- Get insight into how to handle CPU-intensive tasks
To accomplish this, we’ll divide this chapter into the following sections:
- What is a future?
- Leaf futures
- Non-leaf futures
- Runtimes
- A mental model of an async runtime
- What the Rust language and standard library take care of
- I/O vs CPU-intensive tasks
- Advantages and disadvantages of Rust’s async model
What is a future?
A future is a representation of some operation that will be completed in the future.
Async in Rust uses a poll-based approach in which an asynchronous task will have three phases:
- The poll phase: A future is polled, which results in the task progressing until a point where it can no longer make progress. We often refer to the part of the runtime that polls a future as an executor.
- The wait phase: An event source, most often referred to as a reactor, registers that a future is waiting for an event to happen and makes sure that it will wake the future when that event is ready.
- The wake phase: The event happens and the future is woken up. It’s now up to the executor that polled the future in step 1 to schedule the future to be polled again and make further progress until it completes or reaches a new point where it can’t make further progress and the cycle repeats.
Now, when we talk about futures, I find it useful to make a distinction between non-leaf futures and leaf futures early on because, in practice, they’re pretty different from one another.