crossbeam-ring-channel

Crates.iocrossbeam-ring-channel
lib.rscrossbeam-ring-channel
version0.1.0
created_at2026-01-21 15:59:46.859362+00
updated_at2026-01-21 15:59:46.859362+00
descriptionRing-buffer channel with crossbeam-channel compatible select!
homepage
repositoryhttps://github.com/Zetier/crossbeam-ring-channel
max_upload_size
id2059598
size59,638
Joe Kale (jkalez)

documentation

https://docs.rs/crossbeam-ring-channel

README

crossbeam-ring-channel

A small Rust crate that adds a ring-buffer channel alongside crossbeam-channel, plus a Select wrapper that can mix ring receivers with standard crossbeam-channel send/recv operations.

What it provides

  • ring_bounded(capacity): a bounded, ring-buffer channel.
  • RingSender / RingReceiver: sender/receiver halves with familiar methods.
  • Select + select! / select_biased!: crossbeam-style selection that works with ring receivers and crossbeam-channel send/recv operations.

Semantics

  • The ring channel is bounded and non-blocking on send.
  • When full, send evicts the oldest item in the buffer to make room for the new one.
  • recv blocks until an item is available or all senders are dropped.

Installation

Add to your Cargo.toml:

[dependencies]
crossbeam-ring-channel = "0.1"
crossbeam-channel = "0.5" # needed if you use crossbeam-channel receivers/senders in Select

Usage

Basic ring channel:

use crossbeam_ring_channel::ring_bounded;

let (tx, rx) = ring_bounded(2);

// Sends never block; the oldest item is dropped when full.
tx.send("a").unwrap();
tx.send("b").unwrap();
tx.send("c").unwrap();

assert_eq!(rx.recv().unwrap(), "b");
assert_eq!(rx.recv().unwrap(), "c");

Selecting over ring receivers and crossbeam-channel receivers:

use crossbeam_channel::unbounded;
use crossbeam_ring_channel::{ring_bounded, Select};

let (ring_tx, ring_rx) = ring_bounded::<i32>(1);
let (tx, rx) = unbounded::<i32>();

ring_tx.send(1).unwrap();
tx.send(2).unwrap();

let mut sel = Select::new();
let ring_idx = sel.recv(&ring_rx);
let cb_idx = sel.recv(&rx);

let oper = sel.select();
match oper.index() {
    i if i == ring_idx => {
        let value = oper.recv(&ring_rx).unwrap();
        assert_eq!(value, 1);
    }
    i if i == cb_idx => {
        let value = oper.recv(&rx).unwrap();
        assert_eq!(value, 2);
    }
    _ => unreachable!(),
}

Macro selection:

use crossbeam_ring_channel::{ring_bounded, select};

let (tx, rx) = ring_bounded::<i32>(1);
tx.send(42).unwrap();

select! {
    recv(rx) -> msg => {
        assert_eq!(msg.unwrap(), 42);
    },
}

API overview

  • ring_bounded(size)
  • RingSender<T> / RingReceiver<T>
    • send, recv, try_recv, recv_timeout
    • len, capacity, is_empty, is_full, same_channel
  • Select and SelectedOperation
  • Macros: select!, select_biased!
Commit count: 8

cargo fmt