use tokio::signal::unix; use tokio::time; const ADV_INTERVAL: u64 = 1; #[derive(Debug)] enum VRRPv2State { Initialize, Backup, Master, } struct StateMachine { state: VRRPv2State, } impl StateMachine { fn new() -> Self { StateMachine { state: VRRPv2State::Initialize, } } fn transit_to(&mut self, new_state: VRRPv2State) { std::println!("vvrpd: {:?} -> {:?}", self.state, new_state); self.state = new_state; } } async fn advert_handler() { println!("advert timer fired"); } async fn sighup_handler() { println!("got SIGHUP"); } #[tokio::main(flavor = "current_thread")] async fn main() { let advert_timer_handle = tokio::spawn(async move { let mut advert_interval = time::interval(time::Duration::from_secs(ADV_INTERVAL)); loop { advert_interval.tick().await; advert_handler().await; } }); let sighup_handle = tokio::spawn(async move { let mut stream = unix::signal(unix::SignalKind::hangup()).expect("Should be a signal stream"); loop { stream.recv().await; sighup_handler().await; } }); let mut sm = StateMachine::new(); sm.transit_to(VRRPv2State::Master); sm.transit_to(VRRPv2State::Backup); tokio::try_join!(advert_timer_handle, sighup_handle).expect("task(s) erred"); }