use dcl_data_structures::ring_buffer::prelude::*;
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
#[allow(dead_code)]
struct PrintHandler {
producer_counts: [i32; 3],
}
impl PrintHandler {
fn new() -> Self {
Self {
producer_counts: [0; 3],
}
}
}
impl EventHandler<(i32, usize)> for PrintHandler {
fn handle_event(&self, event: &(i32, usize), sequence: u64, end_of_batch: bool) {
let (value, producer_id) = *event;
println!(
"Print handler: value {} from producer {} at sequence {}",
value, producer_id, sequence
);
if end_of_batch {
println!("Print handler batch ended at sequence {}", sequence);
}
}
}
struct MultiplyHandler;
impl EventHandlerMut<(i32, usize)> for MultiplyHandler {
fn handle_event(&mut self, event: &mut (i32, usize), sequence: u64, _end_of_batch: bool) {
let (value, producer_id) = *event;
*event = (value * 2, producer_id);
println!(
"Multiply handler: new value = {} at sequence {}",
event.0, sequence
);
}
}
struct AddHandler {
running_total: i32,
}
impl AddHandler {
fn new() -> Self {
Self { running_total: 0 }
}
}
impl EventHandlerMut<(i32, usize)> for AddHandler {
fn handle_event(&mut self, event: &mut (i32, usize), sequence: u64, _end_of_batch: bool) {
let (value, producer_id) = *event;
*event = (value + 10, producer_id);
self.running_total += event.0;
println!(
"Add handler: value = {}, running total = {} at sequence {}",
event.0, self.running_total, sequence
);
}
}
fn main() {
println!("\nRunning multi-producer multi-consumer example...");
let start_time = Instant::now();
let (executor, producer) = RustDisruptorBuilder::with_ring_buffer::<(i32, usize), 1024>(1024)
.with_blocking_wait()
.with_multi_producer()
.with_barrier(|scope| {
scope.handle_events(PrintHandler::new());
})
.with_barrier(|scope| {
scope.handle_events_mut(MultiplyHandler);
})
.with_barrier(|scope| {
scope.handle_events_mut(AddHandler::new());
})
.build();
let handle = executor.spawn();
let producer = Arc::new(producer);
let mut producer_handles = vec![];
for producer_id in 0..3 {
let producer = Arc::clone(&producer);
let handle = thread::spawn(move || {
for i in 0..4 {
let value = (producer_id + 1) * (i + 1);
producer.write(
std::iter::once((value as i32, producer_id)),
|slot, _, val| *slot = *val,
);
thread::sleep(Duration::from_millis(10)); }
println!("Producer {} finished", producer_id);
});
producer_handles.push(handle);
}
for handle in producer_handles {
handle.join().unwrap();
}
drop(producer);
handle.join();
let duration = start_time.elapsed();
println!(
"Multi-producer multi-consumer example completed in {:?}",
duration
);
}