diff --git a/src/discovery.rs b/src/discovery.rs index db1930d..62509a3 100644 --- a/src/discovery.rs +++ b/src/discovery.rs @@ -33,12 +33,11 @@ impl JoecalState { loop { tokio::select! { _ = timeout.tick() => { - if let Ok(rstate) = self.running_state.try_lock() - && *rstate == RunningState::Stopping + let rstate = self.running_state.lock().await; + if *rstate == RunningState::Stopping { break; } - dbg!("tick"); }, r = self.socket.recv_from(&mut buf) => { match r { diff --git a/src/lib.rs b/src/lib.rs index f04fd57..0f802e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ pub mod transfer; use std::{ collections::HashMap, net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - sync::Arc, + sync::{Arc, OnceLock}, time::Duration, }; @@ -25,6 +25,8 @@ pub const MULTICAST_IP: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 167); pub const LISTENING_SOCKET_ADDR: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::from_bits(0), DEFAULT_PORT); +type ShutdownSender = mpsc::Sender<()>; + /// Contains the main network and application state for an application session. #[derive(Clone)] pub struct JoecalState { @@ -34,7 +36,7 @@ pub struct JoecalState { pub running_state: Arc>, pub socket: Arc, pub client: reqwest::Client, - stop_tx: std::sync::OnceLock>, + stop_tx: OnceLock, } impl JoecalState { @@ -62,10 +64,10 @@ impl JoecalState { let state = self.clone(); let konfig = config.clone(); let server_handle = { - let (tx, rx) = mpsc::channel(1); + let (tx, shutdown_rx) = mpsc::channel(1); self.stop_tx.get_or_init(|| tx); tokio::spawn(async move { - if let Err(e) = state.start_http_server(rx, &konfig).await { + if let Err(e) = state.start_http_server(shutdown_rx, &konfig).await { eprintln!("HTTP server error: {e}"); } }) @@ -85,12 +87,10 @@ impl JoecalState { let announcement_handle = { tokio::spawn(async move { loop { - if let Ok(rstate) = state.running_state.try_lock() - && *rstate == RunningState::Stopping - { + let rstate = state.running_state.lock().await; + if *rstate == RunningState::Stopping { break; } - if let Err(e) = state.announce(None, &config).await { eprintln!("Announcement error: {e}"); } @@ -104,18 +104,17 @@ impl JoecalState { pub async fn stop(&self) { loop { - if let Ok(mut rstate) = self.running_state.try_lock() { - *rstate = RunningState::Stopping; - if self - .stop_tx - .get() - .expect("Could not get stop signal transmitter") - .send(()) - .await - .is_ok() - { - break; - } + let mut rstate = self.running_state.lock().await; + *rstate = RunningState::Stopping; + if self + .stop_tx + .get() + .expect("Could not get stop signal transmitter") + .send(()) + .await + .is_ok() + { + break; } else { tokio::time::sleep(Duration::from_millis(777)).await; } @@ -131,8 +130,6 @@ impl JoecalState { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RunningState { Running, - Sending, - Receiving, Stopping, } diff --git a/src/main.rs b/src/main.rs index f1074c9..8f9ccd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,7 @@ async fn main() -> error::Result<()> { let config = Config::default(); let (h1, h2, h3) = state.start(&config).await.unwrap(); - let mut app = App::new(state.clone()); + let mut app = App::new(state.clone()).await; let mut terminal = ratatui::init(); let result = app.run(&mut terminal).await; ratatui::restore(); @@ -58,20 +58,24 @@ async fn main() -> error::Result<()> { struct App { state: JoecalState, + rstate: RunningState, } impl App { - pub fn new(state: JoecalState) -> Self { - App { state } + pub async fn new(state: JoecalState) -> Self { + App { + state: state.clone(), + rstate: *state.running_state.lock().await, + } } pub async fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> { loop { terminal.draw(|frame| self.draw(frame))?; self.handle_events().await?; - if let Ok(rstate) = self.state.running_state.try_lock() - && *rstate == RunningState::Stopping - { + let rstate = self.state.running_state.lock().await; + self.rstate = *rstate; + if *rstate == RunningState::Stopping { break; } } @@ -127,12 +131,7 @@ impl Widget for &App { .title_bottom(instructions.centered()) .border_set(border::THICK); - let rs = self - .state - .running_state - .try_lock() - .map(|s| format!("{s:?}")) - .unwrap_or("Just a moment...".into()); + let rs = format!("{:?}", self.rstate); let state_text = Text::from(vec![Line::from(vec!["runstate: ".into(), rs.yellow()])]); Paragraph::new(state_text)