use std::thread;
use std::time::Duration;
use parkring::{LockFreeQueue, PopTimeoutError, PushTimeoutError};
fn main() {
let jobs = LockFreeQueue::<u32>::new(8);
let (processed, idle_ticks) = thread::scope(|s| {
let consumer = s.spawn(|| {
let (mut processed, mut idle_ticks) = (0u32, 0u32);
loop {
match jobs.pop_timeout(Duration::from_millis(20)) {
Ok(_job) => {
thread::sleep(Duration::from_millis(5)); processed += 1;
}
Err(PopTimeoutError::Timeout) => idle_ticks += 1, Err(PopTimeoutError::Closed) => return (processed, idle_ticks),
}
}
});
let mut accepted = 0u32;
let mut shed = 0u32;
for job in 0..100 {
match jobs.push_timeout(job, Duration::from_millis(1)) {
Ok(()) => accepted += 1,
Err(PushTimeoutError::Timeout(_job)) => shed += 1,
Err(PushTimeoutError::Closed(_)) => unreachable!("only closed below"),
}
}
println!("producer: {accepted} accepted, {shed} shed under backpressure");
thread::sleep(Duration::from_millis(100));
jobs.close();
assert!(jobs.push(999).is_err(), "pushes fail once closed");
let (processed, idle_ticks) = consumer.join().unwrap();
assert_eq!(processed, accepted, "every accepted job is processed");
(processed, idle_ticks)
});
println!("consumer: processed {processed}, idle {idle_ticks} times, exited after close");
}