Skip to content
mahdi-shojaeePublic

About

A safe sync/async multi-producer, multi-consumer channel

Topics

Resources

Stars

211 stars

Watchers

4 watching

Forks

Repository files navigation

Loole

A safe async/sync multi-producer multi-consumer channel.

Github Actions Documentation Cargo License

// Async — requires an async runtime such as tokio
#[tokio::main]
async fn main() {
    let (tx, rx) = loole::unbounded();

    tokio::spawn(async move {
        for i in 0..10 {
            tx.send_async(i).await.unwrap();
        }
    });

    let mut sum = 0;
    while let Ok(i) = rx.recv_async().await {
        sum += i;
    }

    assert_eq!(sum, (0..10).sum());
}
// Sync
fn main() {
    let (tx, rx) = loole::unbounded();

    std::thread::spawn(move || {
        for i in 0..10 {
            tx.send(i).unwrap();
        }
    });

    let mut sum = 0;
    while let Ok(i) = rx.recv() {
        sum += i;
    }

    assert_eq!(sum, (0..10).sum());
}

Why Loole?

  • Featureful: Unbounded, bounded and rendezvous channels
  • Safe: no unsafe code (#![forbid(unsafe_code)])
  • Capable: Send and receive operations can be blocking (sync) or non-blocking (async)
  • Simple: Minimal dependencies, fast to compile

Usage

To use Loole, place the following line under the [dependencies] section in your Cargo.toml:

loole = "0.6"

Run Benchmarks

Benchmarks measure two metrics:

  • Throughput — the number of messages received per second (higher is better).
  • Latency — the round-trip time for a message to travel from a sender to a receiver and back, in nanoseconds per round trip (lower is better), measured with a single sender/receiver pair exchanging messages back and forth.

Measurements are driven by Criterion.rs: warm-up, sampling, outlier detection, confidence intervals, and regression reports built in. For how to run the suite, configure workloads, and regenerate the charts below, see BENCHMARK.md.

Environment

Reference numbers were measured on Ubuntu Server 26.04.1 LTS with an Intel Core i7-13700K (each run records its toolchain in its machine descriptor, target/criterion/runs/machine-*.json, field rustc_version). The committed chart sets were generated with this command:

taskset -c "0,2,4,6,8,10,12,14" cargo bench -p benchmark --bench criterion_benchmarks -- --worker-threads 8 --crates "flume async-channel tokio kanal crossbeam-channel loole" --isolate-crates --sample-size 10 --measurement-time 5 --warm-up-time 0.5 -m 256

The taskset -c "0,2,4,6,8,10,12,14" prefix pins threads to P-cores and is Linux-only (Windows has a PowerShell affinity equivalent). Adapt the CPU list to the target machine. On macOS there is no CPU-pinning equivalent — run the bare cargo bench … line and prefer pinned runs for verdicts.

The charts below render the default touched mode: each message is a distinct allocation with every byte filled, modeling real payloads whose bytes are all touched (see BENCHMARK.md).

Benchmark Results

Results live in two files:

  • Throughput — messages/s per topology and combo.
  • Latency — SPSC ping-pong round trips plus per-message queueing-delay distributions under load.

Highlights

Flagship async shapes (full galleries in the files above):

Throughput

SPSC async-async throughput MPSC async-async throughput MPMC async-async throughput

Full throughput charts →

Latency

SPSC async-async distribution MPSC async-async distribution MPMC async-async distribution

Full latency charts →

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

A safe sync/async multi-producer, multi-consumer channel

Topics

Resources

Stars

211 stars

Watchers

4 watching

Forks

Used by

Contributors

Languages