node: refactor sync status and thread starting

This commit is contained in:
ardocrat 2023-05-11 20:21:48 +03:00
parent 06f32dcb77
commit 5f3a4b4716
4 changed files with 91 additions and 67 deletions

View file

@ -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;
}

View file

@ -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"),

View file

@ -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
}
}

View file

@ -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<NodeState>, 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<ServerStats>> {
/// Get server stats
pub fn get_stats(&self) -> RwLockReadGuard<'_, Option<ServerStats>> {
self.stats.read().unwrap()
}
/// Get server sync status, empty when server is not running
pub fn get_sync_status(&self) -> Option<SyncStatus> {
// 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<NodeState>, 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);
@ -201,33 +258,3 @@ 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<NodeState>, 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());
}
}
})
}