From a543c177b299029f35340dd70c735698700b58c3 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Tue, 8 Jul 2025 16:31:00 -0700 Subject: [PATCH] more informative shutdown --- src/lib.rs | 45 +++++++++++++++++++++++++-------------------- src/main.rs | 18 ++++++++++++------ src/ui.rs | 4 +--- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1b669e7..0561ab3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ use serde::{Deserialize, Serialize}; use tokio::{ net::UdpSocket, sync::{Mutex, mpsc}, - task::JoinHandle, + task::JoinSet, }; use transfer::Session; @@ -25,7 +25,14 @@ 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<()>; +pub type ShutdownSender = mpsc::Sender<()>; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Listeners { + Udp, + Http, + Multicast, +} /// Contains the main network and backend state for an application session. #[derive(Clone)] @@ -57,35 +64,34 @@ impl JoecalState { }) } - pub async fn start( - &self, - config: &Config, - ) -> crate::error::Result<(JoinHandle<()>, JoinHandle<()>, JoinHandle<()>)> { + pub async fn start(&self, config: &Config, handles: &mut JoinSet) { let state = self.clone(); let konfig = config.clone(); - let server_handle = { + handles.spawn({ let (tx, shutdown_rx) = mpsc::channel(1); self.stop_tx.get_or_init(|| tx); - tokio::spawn(async move { + async move { if let Err(e) = state.start_http_server(shutdown_rx, &konfig).await { eprintln!("HTTP server error: {e}"); } - }) - }; + Listeners::Http + } + }); let state = self.clone(); let konfig = config.clone(); - let udp_handle = { - tokio::spawn(async move { + handles.spawn({ + async move { if let Err(e) = state.listen_multicast(&konfig).await { eprintln!("UDP listener error: {e}"); } - }) - }; + Listeners::Multicast + } + }); let state = self.clone(); let config = config.clone(); - let announcement_handle = { - tokio::spawn(async move { + handles.spawn({ + async move { loop { let rstate = state.running_state.lock().await; if *rstate == RunningState::Stopping { @@ -96,10 +102,9 @@ impl JoecalState { } tokio::time::sleep(std::time::Duration::from_secs(5)).await; } - }) - }; - - Ok((server_handle, udp_handle, announcement_handle)) + Listeners::Udp + } + }); } pub async fn stop(&self) { diff --git a/src/main.rs b/src/main.rs index cb26de2..1506002 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ #![feature(slice_as_array)] use std::{collections::BTreeMap, io, net::SocketAddr}; -use joecalsend::{Config, JoecalState, RunningState, error, models::Device}; +use joecalsend::{Config, JoecalState, error, models::Device}; use local_ip_address::local_ip; use network_interface::{Addr, NetworkInterface, NetworkInterfaceConfig, V4IfAddr}; use ratatui::{ - DefaultTerminal, Frame, + DefaultTerminal, buffer::Buffer, crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind}, layout::Rect, @@ -14,6 +14,7 @@ use ratatui::{ text::{Line, Text}, widgets::{Block, Paragraph, Widget}, }; +use tokio::task::JoinSet; mod ui; @@ -46,14 +47,19 @@ async fn main() -> error::Result<()> { .await .expect("Could not create application session"); let config = Config::default(); - let (h1, h2, h3) = state.start(&config).await.unwrap(); - + let mut handles = JoinSet::new(); + state.start(&config, &mut handles).await; let mut app = App::new(state.clone()).await; let mut terminal = ratatui::init(); let result = app.run(&mut terminal).await; ratatui::restore(); - let _ = tokio::join!(h1, h2, h3); + while let Some(handle) = handles.join_next().await { + match handle { + Ok(h) => println!("Stopped {h:?}"), + Err(e) => println!("Got error {e:?}"), + } + } Ok(result?) } @@ -78,7 +84,7 @@ enum CurrentScreen { impl App { pub async fn new(state: JoecalState) -> Self { App { - state: state.clone(), + state, screen: CurrentScreen::Main, peers: Default::default(), } diff --git a/src/ui.rs b/src/ui.rs index ec60346..48e76f8 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,10 +1,8 @@ -use std::{collections::BTreeMap, net::SocketAddr}; - use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Rect}, style::Stylize, - text::{Line, Span}, + text::Line, widgets::{Block, Borders, List, ListItem}, };