use std::sync::Arc;
use std::thread;
use subms_mpsc_queue::{MpscQueue, PopResult};
const GATEWAYS: usize = 4;
const ORDERS_PER_GATEWAY: usize = 1_000;
fn order_id(gateway: usize, seq: usize) -> u64 {
((gateway as u64) << 32) | seq as u64
}
fn main() {
base_order_fan_in();
#[cfg(feature = "mpmc")]
mpmc_sharded_match();
#[cfg(feature = "bounded")]
bounded_inbox_backpressure();
#[cfg(feature = "batch")]
batch_drain_per_tick();
#[cfg(feature = "metrics")]
metrics_health_snapshot();
#[cfg(feature = "affinity")]
affinity_pin_match_loop();
}
fn base_order_fan_in() {
println!("== base: order-entry gateways fan in to one matching engine ==");
let q: Arc<MpscQueue<u64>> = Arc::new(MpscQueue::new());
let gateways: Vec<_> = (0..GATEWAYS)
.map(|g| {
let q = Arc::clone(&q);
thread::spawn(move || {
for seq in 0..ORDERS_PER_GATEWAY {
q.push(order_id(g, seq));
}
})
})
.collect();
for h in gateways {
h.join().unwrap();
}
let mut q = Arc::into_inner(q).expect("all gateway handles dropped");
let total = GATEWAYS * ORDERS_PER_GATEWAY;
println!(" inbox depth before the match loop starts: {}", q.len());
let first = *q.peek().expect("the inbox is not empty");
println!(
" head of book: gateway {} seq {}",
first >> 32,
first & 0xffff_ffff
);
let mut per_gateway = [0usize; GATEWAYS];
let mut last_seq = [None::<u64>; GATEWAYS];
let mut matched = 0usize;
loop {
match q.try_pop() {
PopResult::Some(order) => {
let g = (order >> 32) as usize;
let seq = order & 0xffff_ffff;
if let Some(prev) = last_seq[g] {
assert!(seq > prev, "orders from one gateway stay in FIFO order");
}
last_seq[g] = Some(seq);
per_gateway[g] += 1;
matched += 1;
}
PopResult::Inconsistent => continue,
PopResult::Empty => break,
}
}
println!(" {GATEWAYS} gateways x {ORDERS_PER_GATEWAY} orders -> matched {matched}");
println!(" per-gateway tally: {per_gateway:?}");
assert_eq!(matched, total, "no order dropped, none duplicated");
for count in per_gateway {
assert_eq!(count, ORDERS_PER_GATEWAY, "every gateway fully drained");
}
for seq in 0..32 {
q.push(order_id(0, seq));
}
let voided = q.clear();
println!(
" kill switch voided {voided} queued orders, inbox empty: {}",
q.is_empty()
);
assert_eq!(voided, 32);
assert!(q.is_empty());
}
#[cfg(feature = "mpmc")]
fn mpmc_sharded_match() {
use std::sync::atomic::{AtomicUsize, Ordering};
use subms_mpsc_queue::MpmcQueue;
println!("\n== mpmc: shard the match loop across several consumers ==");
let shards = 3usize;
let ring: Arc<MpmcQueue<u64>> = Arc::new(MpmcQueue::new(1_024));
let total = GATEWAYS * ORDERS_PER_GATEWAY;
let gateways: Vec<_> = (0..GATEWAYS)
.map(|g| {
let ring = Arc::clone(&ring);
thread::spawn(move || {
for seq in 0..ORDERS_PER_GATEWAY {
let mut order = order_id(g, seq);
while let Err(rejected) = ring.try_enqueue(order) {
order = rejected;
std::hint::spin_loop();
}
}
})
})
.collect();
let matched = Arc::new(AtomicUsize::new(0));
let consumers: Vec<_> = (0..shards)
.map(|_| {
let ring = Arc::clone(&ring);
let matched = Arc::clone(&matched);
thread::spawn(move || {
let mut local = 0usize;
loop {
if ring.try_dequeue().is_some() {
local += 1;
matched.fetch_add(1, Ordering::Relaxed);
} else if matched.load(Ordering::Relaxed) >= total {
break;
} else {
std::hint::spin_loop();
}
}
local
})
})
.collect();
for h in gateways {
h.join().unwrap();
}
let drained: usize = consumers.into_iter().map(|c| c.join().unwrap()).sum();
println!(
" {shards} shards drained {drained} orders, ring empty: {}",
ring.is_empty()
);
assert_eq!(
drained, total,
"shards together drain every order exactly once"
);
assert_eq!(
ring.producer_index(),
ring.consumer_index(),
"every claimed slot was consumed"
);
}
#[cfg(feature = "bounded")]
fn bounded_inbox_backpressure() {
use subms_mpsc_queue::BoundedMpscQueue;
println!("\n== bounded: a fixed-capacity inbox that pushes back ==");
let mut inbox: BoundedMpscQueue<u64> = BoundedMpscQueue::new(4);
let cap = inbox.capacity();
let mut accepted = 0usize;
let mut rejected = 0usize;
for seq in 0..cap + 2 {
match inbox.try_enqueue(order_id(0, seq)) {
Ok(()) => accepted += 1,
Err(_order) => rejected += 1,
}
}
println!(" capacity {cap}: accepted {accepted}, shed {rejected} while full");
assert_eq!(accepted, cap, "accepts exactly one full ring");
assert_eq!(rejected, 2, "the overflow is handed back, not queued");
assert!(inbox.is_full());
assert!(
inbox.try_dequeue().is_some(),
"match loop consumes one order"
);
assert!(
inbox.try_enqueue(order_id(0, 99)).is_ok(),
"a freed slot reopens the inbox"
);
println!(
" producer index {} - consumer index {} = lag {}",
inbox.producer_index(),
inbox.consumer_index(),
inbox.len()
);
assert_eq!(inbox.producer_index() - inbox.consumer_index(), inbox.len());
}
#[cfg(feature = "batch")]
fn batch_drain_per_tick() {
use subms_mpsc_queue::BatchMpscQueue;
println!("\n== batch: publish and drain a whole tick in one pass ==");
const TICK: usize = 256;
const BURST: usize = 50;
let mut q: BatchMpscQueue<u64> = BatchMpscQueue::new();
let total = 1_000usize;
let mut published = 0usize;
while published < total {
let base = published;
published += q.push_batch((base..base + BURST).map(|seq| order_id(0, seq)));
}
println!(" {published} orders published in {} swaps", total / BURST);
assert_eq!(published, total);
let mut buf: Vec<Option<u64>> = (0..TICK).map(|_| None).collect();
let mut ticks = 0usize;
let mut matched = 0usize;
loop {
let n = q.try_dequeue_batch(&mut buf);
if n == 0 {
break;
}
ticks += 1;
for slot in buf.iter_mut().take(n) {
let _ = slot.take();
matched += 1;
}
}
println!(" drained {matched} orders across {ticks} ticks of up to {TICK}");
assert_eq!(matched, total, "every queued order is drained");
assert_eq!(
ticks,
total.div_ceil(TICK),
"each tick drains a full buffer until the tail"
);
q.push_batch((0..64).map(|seq| order_id(1, seq)));
let mut notional = 0u64;
let handled = q.drain(TICK, |order| notional += order & 0xffff_ffff);
println!(" drain callback handled {handled} orders, notional {notional}");
assert_eq!(handled, 64);
assert_eq!(notional, (0..64u64).sum::<u64>());
assert!(q.is_empty());
}
#[cfg(feature = "metrics")]
fn metrics_health_snapshot() {
use subms_mpsc_queue::MetricsMpscQueue;
println!("\n== metrics: a health snapshot of the inbox ==");
let mut q: MetricsMpscQueue<u64> = MetricsMpscQueue::new();
for seq in 0..500 {
q.push(order_id(0, seq));
}
let mut matched = 0usize;
while matched < 500 {
match q.try_pop() {
PopResult::Some(_) => matched += 1,
PopResult::Inconsistent => continue,
PopResult::Empty => break,
}
}
let _ = q.try_pop();
let snap = q.snapshot();
println!(
" enqueue_ok={} dequeue_ok={} dequeue_fail={}",
snap.enqueue_ok, snap.dequeue_ok, snap.dequeue_fail
);
assert_eq!(snap.enqueue_ok, 500, "every push is counted");
assert_eq!(snap.dequeue_ok, 500, "every matched order is counted");
assert!(
snap.dequeue_fail >= 1,
"the miss on the drained queue is counted"
);
}
#[cfg(feature = "affinity")]
fn affinity_pin_match_loop() {
use subms_mpsc_queue::{AffinityError, set_affinity};
println!("\n== affinity: pin the match loop to a core ==");
match set_affinity(&[0]) {
Ok(()) => println!(" match loop pinned to core 0"),
Err(e) => println!(" pinning unavailable: {e}"),
}
assert!(
matches!(set_affinity(&[]), Err(AffinityError::InvalidCore(0))),
"an empty core set is always rejected"
);
}