Tokio
02 / 02

Async I/O, Coordination Primitives & Servers

Async I/O, Coordination Primitives & Servers

Racing Futures with select!

use tokio::time::{timeout, Duration};

tokio::select! {
    res = fetch_from_primary() => println!("primary: {res:?}"),
    res = fetch_from_backup() => println!("backup: {res:?}"),
}

// Bounding how long a call is allowed to take
let res = timeout(Duration::from_secs(2), slow_operation()).await;

select! polls multiple futures concurrently and proceeds with whichever completes first, cancelling the rest — used for racing redundant sources, or (as timeout builds on internally) enforcing a deadline on an operation.

Sharing State Safely Across Tasks

use std::sync::Arc;
use tokio::sync::Mutex;

let counter = Arc::new(Mutex::new(0));

for _ in 0..10 {
    let counter = Arc::clone(&counter);
    tokio::spawn(async move {
        let mut n = counter.lock().await;
        *n += 1;
    });
}

Arc gives shared ownership across tasks; tokio::sync::Mutex (not std::sync::Mutex) yields to the scheduler while waiting for the lock instead of blocking a worker thread — important because holding a std Mutex guard across an .await point can stall other tasks.

Channels for Task Coordination

mpsc lets many producer tasks send values to one consumer — the standard way to hand off data without shared mutable state. oneshot sends exactly one value to exactly one waiting receiver, often used for a result or shutdown signal. broadcast fans a value out to every current subscriber, for pub/sub-style notification.

Building Network Servers

let listener = tokio::net::TcpListener::bind("127.0.0.1:8080").await?;

loop {
    let (socket, _) = listener.accept().await?;
    tokio::spawn(async move {
        handle_connection(socket).await;
    });
}

TcpListener is Tokio's async, non-blocking equivalent of the standard library's blocking listener. Spawning a task per accepted connection is why Tokio-based servers (Axum, Hyper, Tonic all build on it) scale to very high connection counts more cheaply than a thread-per-connection model.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free