Async in Rust

Asynchronous programming usually aim to make it easier to reason about asynchronous operations. For example, by avoiding explicitly working with threads – the asynchronous library handles that itself– you can avoid complexity while avoiding the overhead of unnecessary thread spawning. In Rust, these constructs are ‘tasks.’ When you run a task, instead of blocking, it returns control to the executor thread. The task runs until it would block, then returns Async::Pending. You also provide it a Waker so that it can wake itself up again.

An executor works by running each of the tasks until they block, and then parking. A Waker contains a link back to the executor and inserts the task in the executor’s ready set before unparking it.

Futures are tasks that can be chained. They must implement a type Item that is the result of the computation, a type Error, and a poll method that returns Async::WillWake or Async::Ready(data: Item).

Futures are designed to be state machines: eg, one that alterates between the states Reading and Writing, returning Async::NotReady when it can’t proceed.