use crossbeam::crossbeam_channel::RecvTimeoutError;
use std::error::Error;
use std::time::{Duration, SystemTime};
use tcb::broadcast::broadcast_trait::{GenericReturn, TCB};
use tcb::configuration::middleware_configuration::read_configuration_file;
use tcb::graph::graph::GRAPH;
use tcb::vv::version_vector::VV;
pub fn main() -> Result<(), Box<dyn Error>> {
let group_addresses = vec![format!("localhost:61888")];
generic_client::<GRAPH>(0, 12345, group_addresses)?;
let group_addresses = vec![format!("localhost:61889")];
generic_client::<VV>(0, 54321, group_addresses)?;
Ok(())
}
pub fn generic_client<T: TCB>(
local_id: usize,
local_port: usize,
peer_addresses: Vec<String>,
) -> Result<(), Box<dyn Error>> {
let mut sent_messages = 0;
let configuration_file = format!("path-to-config-file.toml");
let configuration = read_configuration_file(configuration_file)?;
let mut middleware = T::new(local_id, local_port, peer_addresses, configuration);
while sent_messages < 100 {
deliver_messages(&mut middleware)?;
let message = format!("{} {}", local_id, sent_messages);
let serialized_message = message.into_bytes();
let _ = middleware.send(serialized_message);
sent_messages += 1;
}
Ok(())
}
fn deliver_messages<T: TCB>(tcb: &mut T) -> Result<(), Box<dyn Error>> {
let mut now = SystemTime::now();
let end_time = now + Duration::from_secs(10);
let mut delivery_timeout = end_time.duration_since(now).unwrap();
loop {
match tcb.recv_timeout(delivery_timeout) {
Ok(GenericReturn::Delivery(serialized_message, id, cntr)) => {
let delivered_message = String::from_utf8(serialized_message)?;
println!(
"Delivered message -> ({}, {}) {}",
id, cntr, delivered_message
);
}
Ok(GenericReturn::Stable(id, cntr)) => {
println!("Stable message -> ({}, {})", id, cntr);
}
Err(e) => match e {
RecvTimeoutError::Timeout => {
break;
}
RecvTimeoutError::Disconnected => {
panic!("Error was thrown before reading timeout ended");
}
},
}
now = SystemTime::now();
match end_time.duration_since(now) {
Ok(value) => {
delivery_timeout = value;
}
Err(_) => {
break;
}
}
}
Ok(())
}