Skip to main content

Crate rust_tango

Crate rust_tango 

Source
Expand description

A lock-free, high-performance IPC channel inspired by Firedancer’s Tango.

This crate provides a single-producer single-consumer (SPSC) channel optimized for low-latency, high-throughput message passing. It uses lock-free algorithms with busy-polling for minimal latency.

§Features

  • Zero-copy reads: Access message payloads directly without allocation
  • Lock-free: No mutexes, just atomic operations with careful memory ordering
  • Backpressure: Optional credit-based flow control via Fctl
  • Overrun detection: Consumers detect when they’ve been lapped by producers
  • Metrics: Built-in observability with Metrics
  • no_std support: Works in embedded/kernel environments (disable std feature)

§Architecture

  • MCache: Ring buffer of fragment metadata with sequence-based validation
  • DCache: Fixed-size chunk storage for payloads
  • Producer / Consumer: Ergonomic publish and consume APIs
  • Fctl: Credit counter for backpressure
  • Fseq: Shared sequence counter

§Quick Start

use rust_tango::{Consumer, DCache, Fseq, MCache, Producer};

// Create the channel components
let mcache = MCache::<64>::new();      // 64-slot metadata ring buffer
let dcache = DCache::<64, 256>::new(); // 64 chunks of 256 bytes each
let fseq = Fseq::new(1);               // Sequence counter starting at 1

let producer = Producer::new(&mcache, &dcache, &fseq);
let mut consumer = Consumer::new(&mcache, &dcache, 1);

// Publish a message
producer.publish(b"hello", 0, 0, 0).unwrap();

// Consume it (zero-copy)
if let Ok(Some(fragment)) = consumer.poll() {
    assert_eq!(fragment.payload.as_slice(), b"hello");
}

§With Flow Control

Use Fctl to prevent the producer from overwriting unconsumed messages:

use rust_tango::{Consumer, DCache, Fctl, Fseq, MCache, Producer};

let mcache = MCache::<64>::new();
let dcache = DCache::<64, 256>::new();
let fseq = Fseq::new(1);
let fctl = Fctl::new(64); // 64 credits = buffer capacity

let producer = Producer::with_flow_control(&mcache, &dcache, &fseq, &fctl);
let mut consumer = Consumer::with_flow_control(&mcache, &dcache, &fctl, 1);

// Producer blocks when buffer is full (returns NoCredits error)
// Consumer automatically releases credits after consuming

§With Metrics

Track throughput, lag, and errors:

use rust_tango::{Consumer, DCache, Fseq, MCache, Metrics, Producer};

let mcache = MCache::<64>::new();
let dcache = DCache::<64, 256>::new();
let fseq = Fseq::new(1);
let metrics = Metrics::new();

let producer = Producer::new(&mcache, &dcache, &fseq)
    .with_metrics(&metrics);
let mut consumer = Consumer::new(&mcache, &dcache, 1)
    .with_metrics(&metrics);

// ... publish and consume ...

let snapshot = metrics.snapshot();
println!("Lag: {} messages", snapshot.lag());

§Performance Characteristics

Benchmarked on Apple M3 Pro (1000 samples, 10K messages, 64-byte payload):

ScenarioTangostdcrossbeamringbuf
SPSC throughput26.6M msg/s9.1M msg/s7.3M msg/s10.7M msg/s
Ping-pong latency (100 trips)90 µs380 µs105 µs100 µs
Large payload (1KB)12.4 GiB/s-6.9 GiB/s9.4 GiB/s

Best suited for:

  • Single-producer single-consumer scenarios
  • Latency-sensitive applications
  • High-throughput message passing
  • When you can dedicate a core to busy-polling

§Memory Ordering

The lock-free protocol:

  1. Producer writes payload to DCache
  2. Producer writes metadata to MCache slot
  3. Producer stores sequence number with Release ordering
  4. Consumer loads sequence with Acquire, reads metadata, re-checks sequence

This double-read validation detects overwrites without locks.

Structs§

ChannelBuilder
Builder for creating tango channels with ergonomic configuration.
Cnc
Consumer
ConsumerIter
An iterator over fragments from a Consumer.
DCache
DcacheView
Fctl
Fragment
FragmentMetadata
Fseq
MCache
Metrics
Metrics for observability and monitoring.
MetricsSnapshot
A point-in-time snapshot of metrics.
Producer
Tcache
Lock-free tag cache using a hashed bitset.

Enums§

CncState
Command-and-control state for coordinating threads.
ReadResult
Result of attempting to read from the MCache.
TangoError
Errors that can occur during tango operations.