Async in Rust


Back to index

Async foundations in core

  • Rust's libcore gained async capabilities in 1.39
  • Provides mechanisms to handle futures
  • No actual runtime!

Lazy futures

  • In Rust all Future types are lazy
  • That means they don't "make progress" unless polled
  • This is different in other runtime systems

Creating a future alone does nothing!


let fut = MyFuture::new(data, config); // impl Future for MyFuture { ... }

/// Either of these only work in an async function!
// fut.await;
// futures::poll!(fut);

Future lifecycle

future-lifecycle.png

The important types at a glance

These can be found in core::future and core::task

Future
Primary future abstraction trait
Poll
Enum to indicate runtime completion of a future
Waker
A mechanism to wake up a future after it has yielded

Future vs Task

Think of a Future as a single step in a chain of async operations.

A task is the chain.

No runtime in std!

  • Rust doesn't include a runtime in its std library (for good reason!)
  • All the programming excercises are solvable with smol-rs, a very smol async runtime

What is a Runtime?

  • Process data, handle I/O
  • Schedule available work in an effective way
  • Interleave work as it becomes available
  • De-allocate futures that are no longer needed

Stopping ongoing work


  • Because futures are lazy they can be cancelled (most of the time)
  • This might result in partial state (← how do you handle this?)

The real lifecycle


Any future can be cancelled at any point!

future-lifecycle2.png

Your async application is a Runtime!

Yeah okay but like… really?

tokio

  • Probably needs to introduction
  • Started in 2016 by Carl Lerche
[dependencies]
tokio = { version = "1.0", features = ["full"] }
#[tokio::main]
async fn main() {
    // your async code here
}

async-std

  • Started in 2019 by Stjepan Glavina
  • Maintained by the "Async Rust WG"
[dependencies]
async-std = { version = "1.0", features = ["attribute"] }
#[async_std::main]
async fn main() {
    // your async code here
}

smol-rs

  • The actual event reactor behind async-std!
  • A bit more clumbsy to use, but just as powerful
  • This makes it more embeddable
fn main() {
    smol::block_on(async {
        // your async code here
    });
}

Different runtimes focus on different UX strategies

Back to index