node: refactor sync status and thread starting
This commit is contained in:
parent
06f32dcb77
commit
5f3a4b4716
4 changed files with 91 additions and 67 deletions
|
@ -26,5 +26,5 @@ mod network_metrics;
|
||||||
|
|
||||||
pub trait NetworkTab {
|
pub trait NetworkTab {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui, node: &mut crate::node::Node);
|
fn ui(&mut self, ui: &mut egui::Ui, node: &mut crate::node::Node);
|
||||||
fn title(&self) -> &String;
|
fn name(&self) -> &String;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ impl Network {
|
||||||
self.draw_tabs(ui);
|
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) {
|
fn draw_tabs(&self, ui: &mut egui::Ui) {
|
||||||
|
@ -166,19 +166,17 @@ impl Network {
|
||||||
|
|
||||||
let title_text = match &self.current_mode {
|
let title_text = match &self.current_mode {
|
||||||
Mode::Node => {
|
Mode::Node => {
|
||||||
self.node_view.title()
|
self.node_view.name()
|
||||||
}
|
}
|
||||||
Mode::Metrics => {
|
Mode::Metrics => {
|
||||||
self.node_view.title()
|
self.node_view.name()
|
||||||
}
|
}
|
||||||
Mode::Tuning => {
|
Mode::Tuning => {
|
||||||
self.node_view.title()
|
self.node_view.name()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let r_stats = node.state.read_stats();
|
let syncing = node.state.is_syncing();
|
||||||
let syncing = r_stats.is_some() &&
|
|
||||||
r_stats.as_ref().unwrap().sync_status != SyncStatus::NoSync;
|
|
||||||
|
|
||||||
let mut b = builder.size(Size::remainder());
|
let mut b = builder.size(Size::remainder());
|
||||||
if syncing {
|
if syncing {
|
||||||
|
@ -193,12 +191,11 @@ impl Network {
|
||||||
if syncing {
|
if syncing {
|
||||||
strip.cell(|ui| {
|
strip.cell(|ui| {
|
||||||
ui.centered_and_justified(|ui| {
|
ui.centered_and_justified(|ui| {
|
||||||
let status_text = if node.state.is_stopping() {
|
let status_text = if node.state.is_restarting() {
|
||||||
get_sync_status(SyncStatus::Shutdown).to_string()
|
|
||||||
} else if node.state.is_restarting() {
|
|
||||||
"Restarting".to_string()
|
"Restarting".to_string()
|
||||||
} else {
|
} 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 {
|
let mut job = LayoutJob::single_section(status_text, TextFormat {
|
||||||
font_id: FontId::proportional(15.0),
|
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 {
|
match sync_status {
|
||||||
SyncStatus::Initial => Cow::Borrowed("Initializing"),
|
SyncStatus::Initial => Cow::Borrowed("Initializing"),
|
||||||
SyncStatus::NoSync => Cow::Borrowed("Running"),
|
SyncStatus::NoSync => Cow::Borrowed("Running"),
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl NetworkTab for NetworkNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.button("re-start").clicked() {
|
if ui.button("re-start").clicked() {
|
||||||
node.restart(ChainTypes::Mainnet);
|
node.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui.button("start").clicked() {
|
if ui.button("start").clicked() {
|
||||||
|
@ -70,7 +70,7 @@ impl NetworkTab for NetworkNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title(&self) -> &String {
|
fn name(&self) -> &String {
|
||||||
&self.title
|
&self.title
|
||||||
}
|
}
|
||||||
}
|
}
|
131
src/node/node.rs
131
src/node/node.rs
|
@ -42,7 +42,7 @@ impl Node {
|
||||||
pub fn new(chain_type: ChainTypes, start: bool) -> Self {
|
pub fn new(chain_type: ChainTypes, start: bool) -> Self {
|
||||||
let state = Arc::new(NodeState::new(chain_type));
|
let state = Arc::new(NodeState::new(chain_type));
|
||||||
if start {
|
if start {
|
||||||
Self::start_server(state.clone(), chain_type);
|
start_server_thread(state.clone(), chain_type);
|
||||||
}
|
}
|
||||||
Self { state }
|
Self { state }
|
||||||
}
|
}
|
||||||
|
@ -54,22 +54,17 @@ impl Node {
|
||||||
|
|
||||||
/// Start server with provided chain type
|
/// Start server with provided chain type
|
||||||
pub fn start(&self, chain_type: ChainTypes) {
|
pub fn start(&self, chain_type: ChainTypes) {
|
||||||
if !self.state.is_restarting() && !self.state.is_running() {
|
if !self.state.is_running() {
|
||||||
Self::start_server(self.state.clone(), chain_type);
|
start_server_thread(self.state.clone(), chain_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_server(state: Arc<NodeState>, chain_type: ChainTypes) {
|
/// Restart server or start when not running
|
||||||
let server = start_server(&chain_type);
|
pub fn restart(&mut self) {
|
||||||
start_server_thread(state, server);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Restart server with provided chain type
|
|
||||||
pub fn restart(&mut self, chain_type: ChainTypes) {
|
|
||||||
if self.state.is_running() {
|
if self.state.is_running() {
|
||||||
self.state.restart_needed.store(true, Ordering::Relaxed);
|
self.state.restart_needed.store(true, Ordering::Relaxed);
|
||||||
} else {
|
} 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
|
/// Check if server is stopping
|
||||||
pub fn is_stopping(&self) -> bool {
|
pub fn is_stopping(&self) -> bool {
|
||||||
return self.stop_needed.load(Ordering::Relaxed)
|
self.stop_needed.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if server is restarting
|
/// Check if server is restarting
|
||||||
pub fn is_restarting(&self) -> bool {
|
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 {
|
/// Get server stats
|
||||||
self.read_stats().is_some()
|
pub fn get_stats(&self) -> RwLockReadGuard<'_, Option<ServerStats>> {
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_stats(&self) -> RwLockReadGuard<'_, Option<ServerStats>> {
|
|
||||||
self.stats.read().unwrap()
|
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
|
/// 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();
|
let server_config = config.members.as_ref().unwrap().server.clone();
|
||||||
|
|
||||||
// Remove lock file (in case if we have running node from another app)
|
// 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");
|
let mut db_path = PathBuf::from(&server_config.db_root);
|
||||||
fs::remove_file(db_path).unwrap();
|
db_path.push("grin.lock");
|
||||||
|
fs::remove_file(db_path).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize our global chain_type, feature flags (NRD kernel support currently),
|
// Initialize our global chain_type, feature flags (NRD kernel support currently),
|
||||||
// accept_fee_base, and future_time_limit.
|
// accept_fee_base, and future_time_limit.
|
||||||
|
@ -184,7 +241,7 @@ fn start_server(chain_type: &ChainTypes) -> Server {
|
||||||
fs::remove_file(db_path).unwrap();
|
fs::remove_file(db_path).unwrap();
|
||||||
|
|
||||||
// Remove chain data on server start error
|
// 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 {
|
for dir in dirs_to_remove {
|
||||||
let mut path = PathBuf::from(&server_config.db_root);
|
let mut path = PathBuf::from(&server_config.db_root);
|
||||||
path.push(dir);
|
path.push(dir);
|
||||||
|
@ -200,34 +257,4 @@ fn start_server(chain_type: &ChainTypes) -> Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
server_result.unwrap()
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue