crossbeam-ring-channel 0.1.0

Ring-buffer channel with crossbeam-channel compatible select!
Documentation
  • Coverage
  • 100%
    17 out of 17 items documented17 out of 17 items with examples
  • Size
  • Source code size: 59.12 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.42 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 20s Average build duration of successful builds.
  • all releases: 20s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • jkalez

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!