use simulacra::{Duration, NodeContext, NodeId, TaskSimBuilder, TopologyBuilder};
const NODE_COUNT: u32 = 5;
const ELECTION_WINDOW: Duration = Duration::from_millis(50);
async fn elect(ctx: NodeContext<u32>) {
let my_id = ctx.id().as_u32();
for peer in 0..NODE_COUNT {
if peer != my_id {
ctx.send(NodeId(peer), my_id).await;
}
}
let mut best = my_id;
let deadline = ctx.now() + ELECTION_WINDOW;
loop {
let remaining = deadline.saturating_duration_since(ctx.now());
if remaining.is_zero() {
break;
}
match ctx.recv_timeout(remaining).await {
Some(env) => {
if env.payload > best {
best = env.payload;
}
}
None => break,
}
}
println!(
"[{:>10}] Node {} elected leader: {}",
ctx.now(),
my_id,
best
);
}
fn main() {
let topology = TopologyBuilder::new(NODE_COUNT as usize)
.full_mesh(Duration::from_millis(2))
.build();
let sim = TaskSimBuilder::<u32>::new(topology, 0xA1B2C3).build(elect);
let stats = sim.run();
println!("\n--- Simulation Complete ---");
println!("Final time: {}", stats.final_time);
println!("Events processed: {}", stats.events_processed);
println!("Messages delivered: {}", stats.messages_delivered);
println!("Tasks completed: {}", stats.tasks_completed);
}