diff --git a/src/gui/views/mod.rs b/src/gui/views/mod.rs index 9ccc115..c19e1ba 100644 --- a/src/gui/views/mod.rs +++ b/src/gui/views/mod.rs @@ -26,5 +26,5 @@ mod network_metrics; pub trait NetworkTab { fn ui(&mut self, ui: &mut egui::Ui, node: &mut crate::node::Node); - fn title(&self) -> &String; + fn name(&self) -> &String; } diff --git a/src/gui/views/network.rs b/src/gui/views/network.rs index 0e8cb95..d283eff 100644 --- a/src/gui/views/network.rs +++ b/src/gui/views/network.rs @@ -98,7 +98,7 @@ impl Network { self.draw_tabs(ui); }); - ui.ctx().request_repaint_after(Duration::from_millis(500)); + ui.ctx().request_repaint_after(Duration::from_millis(1000)); } fn draw_tabs(&self, ui: &mut egui::Ui) { @@ -166,19 +166,17 @@ impl Network { let title_text = match &self.current_mode { Mode::Node => { - self.node_view.title() + self.node_view.name() } Mode::Metrics => { - self.node_view.title() + self.node_view.name() } Mode::Tuning => { - self.node_view.title() + self.node_view.name() } }; - let r_stats = node.state.read_stats(); - let syncing = r_stats.is_some() && - r_stats.as_ref().unwrap().sync_status != SyncStatus::NoSync; + let syncing = node.state.is_syncing(); let mut b = builder.size(Size::remainder()); if syncing { @@ -193,12 +191,11 @@ impl Network { if syncing { strip.cell(|ui| { ui.centered_and_justified(|ui| { - let status_text = if node.state.is_stopping() { - get_sync_status(SyncStatus::Shutdown).to_string() - } else if node.state.is_restarting() { + let status_text = if node.state.is_restarting() { "Restarting".to_string() } else { - get_sync_status(r_stats.as_ref().unwrap().sync_status).to_string() + let sync_status = node.state.get_sync_status(); + get_sync_status_text(sync_status.unwrap()).to_string() }; let mut job = LayoutJob::single_section(status_text, TextFormat { font_id: FontId::proportional(15.0), @@ -219,7 +216,7 @@ impl Network { } } -fn get_sync_status(sync_status: SyncStatus) -> Cow<'static, str> { +fn get_sync_status_text(sync_status: SyncStatus) -> Cow<'static, str> { match sync_status { SyncStatus::Initial => Cow::Borrowed("Initializing"), SyncStatus::NoSync => Cow::Borrowed("Running"), diff --git a/src/gui/views/network_node.rs b/src/gui/views/network_node.rs index bbd4f34..8c0a859 100644 --- a/src/gui/views/network_node.rs +++ b/src/gui/views/network_node.rs @@ -62,7 +62,7 @@ impl NetworkTab for NetworkNode { } if ui.button("re-start").clicked() { - node.restart(ChainTypes::Mainnet); + node.restart(); } if ui.button("start").clicked() { @@ -70,7 +70,7 @@ impl NetworkTab for NetworkNode { } } - fn title(&self) -> &String { + fn name(&self) -> &String { &self.title } } \ No newline at end of file diff --git a/src/node/node.rs b/src/node/node.rs index cd0c76b..1250109 100644 --- a/src/node/node.rs +++ b/src/node/node.rs @@ -42,7 +42,7 @@ impl Node { pub fn new(chain_type: ChainTypes, start: bool) -> Self { let state = Arc::new(NodeState::new(chain_type)); if start { - Self::start_server(state.clone(), chain_type); + start_server_thread(state.clone(), chain_type); } Self { state } } @@ -54,22 +54,17 @@ impl Node { /// Start server with provided chain type pub fn start(&self, chain_type: ChainTypes) { - if !self.state.is_restarting() && !self.state.is_running() { - Self::start_server(self.state.clone(), chain_type); + if !self.state.is_running() { + start_server_thread(self.state.clone(), chain_type); } } - fn start_server(state: Arc, chain_type: ChainTypes) { - let server = start_server(&chain_type); - start_server_thread(state, server); - } - - /// Restart server with provided chain type - pub fn restart(&mut self, chain_type: ChainTypes) { + /// Restart server or start when not running + pub fn restart(&mut self) { if self.state.is_running() { self.state.restart_needed.store(true, Ordering::Relaxed); } else { - self.start(chain_type); + self.start(*self.state.chain_type); } } } @@ -96,23 +91,83 @@ impl NodeState { } } + /// Check if server is running when stats are not empty + pub fn is_running(&self) -> bool { + self.get_stats().is_some() + } + /// Check if server is stopping pub fn is_stopping(&self) -> bool { - return self.stop_needed.load(Ordering::Relaxed) + self.stop_needed.load(Ordering::Relaxed) } /// Check if server is restarting pub fn is_restarting(&self) -> bool { - return self.restart_needed.load(Ordering::Relaxed) + self.restart_needed.load(Ordering::Relaxed) } - pub fn is_running(&self) -> bool { - self.read_stats().is_some() - } - - pub fn read_stats(&self) -> RwLockReadGuard<'_, Option> { + /// Get server stats + pub fn get_stats(&self) -> RwLockReadGuard<'_, Option> { self.stats.read().unwrap() } + + /// Get server sync status, empty when server is not running + pub fn get_sync_status(&self) -> Option { + // return shutdown status when node is stopping + if self.is_stopping() { + return Some(SyncStatus::Shutdown) + } + + let stats = self.get_stats(); + // return sync status when server is running (stats are not empty) + if stats.is_some() { + return Some(stats.as_ref().unwrap().sync_status) + } + None + } + + /// Check if server is syncing based on sync status + pub fn is_syncing(&self) -> bool { + let sync_status = self.get_sync_status(); + match sync_status { + None => { self.is_restarting() } + Some(s) => { s!= SyncStatus::NoSync } + } + } +} + +/// Start a thread to launch server and update node state with server stats +fn start_server_thread(state: Arc, chain_type: ChainTypes) -> JoinHandle<()> { + thread::spawn(move || { + let mut server = start_server(&chain_type); + + loop { + thread::sleep(Duration::from_millis(500)); + + if state.is_restarting() { + server.stop(); + + // Create new server with current chain type + server = start_server(&state.chain_type); + + state.restart_needed.store(false, Ordering::Relaxed); + } else if state.is_stopping() { + server.stop(); + + let mut w_stats = state.stats.write().unwrap(); + *w_stats = None; + + state.stop_needed.store(false, Ordering::Relaxed); + break; + } else { + let stats = server.get_server_stats(); + if stats.is_ok() { + let mut w_stats = state.stats.write().unwrap(); + *w_stats = Some(stats.as_ref().ok().unwrap().clone()); + } + } + } + }) } /// Start server with provided chain type @@ -135,9 +190,11 @@ fn start_server(chain_type: &ChainTypes) -> Server { let server_config = config.members.as_ref().unwrap().server.clone(); // Remove lock file (in case if we have running node from another app) - let mut db_path = PathBuf::from(&server_config.db_root); - db_path.push("grin.lock"); - fs::remove_file(db_path).unwrap(); + { + let mut db_path = PathBuf::from(&server_config.db_root); + db_path.push("grin.lock"); + fs::remove_file(db_path).unwrap(); + } // Initialize our global chain_type, feature flags (NRD kernel support currently), // accept_fee_base, and future_time_limit. @@ -184,7 +241,7 @@ fn start_server(chain_type: &ChainTypes) -> Server { fs::remove_file(db_path).unwrap(); // Remove chain data on server start error - let dirs_to_remove: Vec<&str> = vec!["header", "lmdb", "txhashset", "peer"]; + let dirs_to_remove: Vec<&str> = vec!["header", "lmdb", "txhashset"]; for dir in dirs_to_remove { let mut path = PathBuf::from(&server_config.db_root); path.push(dir); @@ -200,34 +257,4 @@ fn start_server(chain_type: &ChainTypes) -> Server { } server_result.unwrap() -} - -/// Start a thread to launch server and update node state with server stats -fn start_server_thread(state: Arc, mut server: Server) -> JoinHandle<()> { - thread::spawn(move || loop { - thread::sleep(Duration::from_millis(500)); - - if state.is_restarting() { - server.stop(); - - // Create new server with current chain type - server = start_server(&state.chain_type); - - state.restart_needed.store(false, Ordering::Relaxed); - } else if state.is_stopping() { - server.stop(); - - let mut w_stats = state.stats.write().unwrap(); - *w_stats = None; - - state.stop_needed.store(false, Ordering::Relaxed); - break; - } else { - let stats = server.get_server_stats(); - if stats.is_ok() { - let mut w_stats = state.stats.write().unwrap(); - *w_stats = Some(stats.as_ref().ok().unwrap().clone()); - } - } - }) } \ No newline at end of file