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_stdsupport: Works in embedded/kernel environments (disablestdfeature)
§Architecture
MCache: Ring buffer of fragment metadata with sequence-based validationDCache: Fixed-size chunk storage for payloadsProducer/Consumer: Ergonomic publish and consume APIsFctl: Credit counter for backpressureFseq: 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):
| Scenario | Tango | std | crossbeam | ringbuf |
|---|---|---|---|---|
| SPSC throughput | 26.6M msg/s | 9.1M msg/s | 7.3M msg/s | 10.7M msg/s |
| Ping-pong latency (100 trips) | 90 µs | 380 µs | 105 µs | 100 µs |
| Large payload (1KB) | 12.4 GiB/s | - | 6.9 GiB/s | 9.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:
- Producer writes payload to
DCache - Producer writes metadata to
MCacheslot - Producer stores sequence number with
Releaseordering - Consumer loads sequence with
Acquire, reads metadata, re-checks sequence
This double-read validation detects overwrites without locks.
Structs§
- Channel
Builder - Builder for creating tango channels with ergonomic configuration.
- Cnc
- Consumer
- Consumer
Iter - An iterator over fragments from a
Consumer. - DCache
- Dcache
View - Fctl
- Fragment
- Fragment
Metadata - Fseq
- MCache
- Metrics
- Metrics for observability and monitoring.
- Metrics
Snapshot - 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.
- Read
Result - Result of attempting to read from the MCache.
- Tango
Error - Errors that can occur during tango operations.