p2pool: use [Arc<Mutex<Ping>>] as intermediary for node auto-select

This commit is contained in:
hinto-janaiyo 2022-11-16 16:07:49 -05:00
parent 1b85e59530
commit bd6f369b56
No known key found for this signature in database
GPG key ID: B1C5A64B80691E45
3 changed files with 41 additions and 34 deletions

View file

@ -35,7 +35,7 @@ use env_logger::{Builder,WriteStyle};
// Regex
use regex::Regex;
// std
use std::io::Write;
use std::process::exit;
@ -63,13 +63,13 @@ use {ferris::*,constants::*,node::*,disk::*,status::*,update::*};
pub struct App {
// Misc state
tab: Tab, // What tab are we on?
ping: Arc<Mutex<Ping>>, // Ping data found in [node.rs]
width: f32, // Top-level width
height: f32, // Top-level height
// State
og: Arc<Mutex<State>>, // og = Old state to compare against
state: State, // state = Working state (current settings)
update: Arc<Mutex<Update>>, // State for update data [update.rs]
ping: Arc<Mutex<Ping>>, // Ping data found in [node.rs]
og_node_vec: Vec<(String, Node)>, // Manual Node database
node_vec: Vec<(String, Node)>, // Manual Node database
diff: bool, // This bool indicates state changes
@ -678,11 +678,6 @@ impl eframe::App for App {
return
}
// The [P2Pool Node] selection needs to be the same
// for both [State] and [Og] because of [Auto-select]
// Wrapping [node] within an [Arc<Mutex>] is a lot more work
// so sending it into the [Ping] thread is not viable.
self.state.p2pool.node = self.og.lock().unwrap().p2pool.node;
// Compare [og == state] and the [node_vec] and enable diff if found.
// The struct fields are compared directly because [Version]
// contains Arc<Mutex>'s that cannot be compared easily.

View file

@ -96,6 +96,7 @@ pub struct Ping {
pub msg: String,
pub prog: f32,
pub pinged: bool,
pub auto_selected: bool,
}
impl Ping {
@ -107,16 +108,11 @@ impl Ping {
msg: "No ping in progress".to_string(),
prog: 0.0,
pinged: false,
auto_selected: true,
}
}
}
#[derive(Debug)]
pub struct PingResult {
pub nodes: Vec<NodeData>,
pub fastest: NodeEnum,
}
//---------------------------------------------------------------------------------------------------- IP <-> Enum functions
// Function for returning IP/Enum
pub fn ip_to_enum(ip: &'static str) -> NodeEnum {
@ -317,15 +313,16 @@ pub fn ping(ping: Arc<Mutex<Ping>>, og: Arc<Mutex<State>>) {
}
let info = format!("Fastest node: {}ms ... {} @ {}", best_ms, fastest, enum_to_ip(fastest));
info!("Ping | {}", info);
ping.lock().unwrap().nodes = nodes;
ping.lock().unwrap().fastest = fastest;
ping.lock().unwrap().prog = 100.0;
ping.lock().unwrap().msg = info;
ping.lock().unwrap().pinging = false;
ping.lock().unwrap().pinged = true;
let mut guard = ping.lock().unwrap();
guard.nodes = nodes;
guard.fastest = fastest;
guard.prog = 100.0;
guard.msg = info;
guard.pinging = false;
guard.pinged = true;
drop(guard);
if og.lock().unwrap().p2pool.auto_select {
og.lock().unwrap().p2pool.node = fastest;
og.lock().unwrap().save();
ping.lock().unwrap().auto_selected = false;
}
info!("Ping ... OK");
}

View file

@ -84,6 +84,22 @@ impl P2pool {
let height = height / 6.0;
ui.spacing_mut().slider_width = width - 8.0;
ui.spacing_mut().icon_width = width / 25.0;
// [Auto-select] if we haven't already.
// Using [Arc<Mutex<Ping>>] as an intermediary here
// saves me the hassle of wrapping [state: State] completely
// and [.lock().unwrap()]ing it everywhere.
// Two atomic bools = enough to represent this data
if self.auto_select {
let mut ping = ping.lock().unwrap();
// If we haven't auto_selected yet, auto-select and turn it off
if ping.auto_selected == false {
self.node = ping.fastest;
ping.auto_selected = true;
}
drop(ping);
}
ui.vertical(|ui| {
ui.horizontal(|ui| {
// [Ping List]
@ -91,15 +107,17 @@ impl P2pool {
let ip = enum_to_ip(id);
let mut ms = 0;
let mut color = Color32::LIGHT_GRAY;
for data in ping.lock().unwrap().nodes.iter() {
if data.id == id {
ms = data.ms;
color = data.color;
break
if ping.lock().unwrap().pinged {
for data in ping.lock().unwrap().nodes.iter() {
if data.id == id {
ms = data.ms;
color = data.color;
break
}
}
}
let text = RichText::new(format!("{}ms | {} | {}", ms, id, ip)).color(color);
ComboBox::from_id_source("nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
ComboBox::from_id_source("community_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
for data in ping.lock().unwrap().nodes.iter() {
let ms = crate::node::format_ms(data.ms);
let id = crate::node::format_enum(data.id);
@ -115,13 +133,11 @@ impl P2pool {
let width = (width/2.0)-4.0;
// [Select fastest node]
if ui.add_sized([width, height], Button::new("Select fastest node")).on_hover_text(P2POOL_SELECT_FASTEST).clicked() {
let pinged = ping.lock().unwrap().pinged;
let fastest = ping.lock().unwrap().fastest;
if pinged && og.lock().unwrap().p2pool.node != fastest {
og.lock().unwrap().p2pool.node = ping.lock().unwrap().fastest;
og.lock().unwrap().save();
if ping.lock().unwrap().pinged {
self.node = ping.lock().unwrap().fastest;
}
}
// [Ping Button]
ui.set_enabled(!ping.lock().unwrap().pinging);
if ui.add_sized([width, height], Button::new("Ping community nodes")).on_hover_text(P2POOL_PING).clicked() {
@ -267,7 +283,7 @@ impl P2pool {
ui.spacing_mut().icon_width = width / 25.0;
// [Ping List]
let text = RichText::new(format!("{}. {} | {}", self.selected_index, self.selected_name, self.selected_ip));
ComboBox::from_id_source("nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
ComboBox::from_id_source("manual_nodes").selected_text(RichText::text_style(text, Monospace)).show_ui(ui, |ui| {
let mut n = 1;
for (name, node) in node_vec.iter() {
let text = RichText::text_style(RichText::new(format!("{}. {}\n IP: {}\n RPC: {}\n ZMQ: {}", n, name, node.ip, node.rpc, node.zmq)), Monospace);
@ -275,7 +291,6 @@ impl P2pool {
self.selected_index = n;
self.selected_name = name.clone();
}
// ui.selectable_value(&mut self.selected_name, name.clone(), text);
n += 1;
}
});