[][src]Crate unicycle

A container for an unordered collection of Futures. This provides an experimental variant of FuturesUnordered aimed to be fairer. Easier to maintain, and store the futures being polled in a way which provides better memory locality.

Architecture

The Unordered type stores all futures being polled in a PinSlab. This slab maintains a growable collection of fixed-size memory regions, allowing it to store immovable objects. The primary feature of a slab is that it automatically reclaims memory at low cost. Each future inserted into the slab is asigned an index.

Next to the futures we maintain two bitsets, one active and one alternate. When a future is woken up, the bit associated with its index is set in the active set, and the waker associated with the poll to Unordered is called.

Once Unordered is polled, it atomically swaps the active and alternate bitsets, waits until it has exclusive access to the now alternate bitset, and drains it from all the indexes which have been flagged to determine which futures to poll.

We can also add futures to Unordered, this is achieved by inserting it into the slab, then marking that index in a special pollable collection that it should be polled the next time Unordered is.

Examples

use tokio::{stream::StreamExt as _, time};
use std::time::Duration;

#[tokio::main]
async fn main() {
    let mut futures = unicycle::Unordered::new();

    futures.push(time::delay_for(Duration::from_secs(2)));
    futures.push(time::delay_for(Duration::from_secs(3)));
    futures.push(time::delay_for(Duration::from_secs(1)));

    while let Some(_) = futures.next().await {
        println!("tick");
    }

    println!("done!");
}

Structs

Unordered

A container for an unordered collection of Futures.