Hi! I'd like feedback on ring, a family of Rust crates for a lock-free write path: many threads send work, and one thread processes it in a strict, reproducible order.
The problem
- With a shared lock, threads pile up waiting for each other ("lock convoy"), and latency jumps unpredictably under load.
- Some systems need every message processed exactly once and in one fixed order, so the result is the same every time it's replayed.
- General-purpose queues are fast, but they aren't built around that exact shape: many producers, one ordered consumer.
What ring does
- No locks: producers claim a slot, write it and publish it, without waiting on a shared lock.
- Exactly once, in order: every record is delivered once, in a reproducible total order.
- Two shapes: single-producer (SPSC) for the lowest overhead, and multi-producer (MPSC) with batch claiming.
- Control when full: you choose what happens when the ring is full (overflow policies), and the producer never overtakes the slowest reader.
- Extras: thread-local staging, wait strategies (spin, yield, park), and clean shutdown with drain.
- Checked:
unsafeis denied across the workspace except in a few justified places; concurrency is tested with loom and fuzzing in CI.
let mut ring = Factory.build::< u32 >( RingConfig::new( 8 )? )?; let ( mut producer, mut consumer ) = ring.ends().split(); producer.try_push( 7 )?; assert_eq!( consumer.drain().next(), Some( 7 ) ); Results, honestly
Benchmarked against 11 alternatives (rtrb, ringbuf, crossbeam, flume, ArrayQueue and others) on one machine:
- Single producer: up to +83% throughput over the fastest alternative (rtrb); a tie on single-record latency (3.5 ns).
- Many producers, batched: leads its class.
- Many producers, one record at a time: 2–4× slower than
ArrayQueueandcrossbeam-channel. This is the weak spot.
Questions
- Any common pitfalls in lock-free queues I should test for?
- How would you speed up the unbatched multi-producer path?
Thanks!
1 post - 1 participant
