mirror of
https://github.com/thegeneralist01/p2p-failover
synced 2026-01-11 07:30:40 +01:00
use anyhow for errors
This commit is contained in:
parent
ee83a166ce
commit
5b4bc54c1f
4 changed files with 43 additions and 45 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -43,9 +43,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.95"
|
version = "1.0.97"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
|
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
|
|
@ -879,6 +879,7 @@ dependencies = [
|
||||||
name = "p2p-failover"
|
name = "p2p-failover"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dateparser",
|
"dateparser",
|
||||||
"notify",
|
"notify",
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,4 @@ serde_yaml = "0.9"
|
||||||
reqwest = "0.12.12"
|
reqwest = "0.12.12"
|
||||||
tokio = { version = "=1.40.0", features = ["full"] }
|
tokio = { version = "=1.40.0", features = ["full"] }
|
||||||
notify = "8.0.0"
|
notify = "8.0.0"
|
||||||
|
anyhow = "1.0.97"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use anyhow::Result;
|
||||||
use p2p_failover::{file_watcher, node::Node, parser::Parser, tcp_listener};
|
use p2p_failover::{file_watcher, node::Node, parser::Parser, tcp_listener};
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
|
|
@ -6,7 +7,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<()> {
|
||||||
let config_path =
|
let config_path =
|
||||||
std::env::var("P2P_CONFIG_PATH").unwrap_or_else(|_| "p2p-failover.config.yaml".to_string());
|
std::env::var("P2P_CONFIG_PATH").unwrap_or_else(|_| "p2p-failover.config.yaml".to_string());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use anyhow::{bail, Result};
|
||||||
use std::{
|
use std::{
|
||||||
io::{BufRead, BufReader},
|
io::{BufRead, BufReader},
|
||||||
sync::mpsc,
|
sync::mpsc,
|
||||||
|
|
@ -25,7 +26,7 @@ pub struct NodeInfo {
|
||||||
pub target: String,
|
pub target: String,
|
||||||
pub port: u32,
|
pub port: u32,
|
||||||
pub preference: u8,
|
pub preference: u8,
|
||||||
stream: Option<TcpStream>,
|
streamp: Option<TcpStream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeInfo {
|
impl NodeInfo {
|
||||||
|
|
@ -34,24 +35,24 @@ impl NodeInfo {
|
||||||
target: String,
|
target: String,
|
||||||
port: u32,
|
port: u32,
|
||||||
preference: u8,
|
preference: u8,
|
||||||
stream: Option<TcpStream>,
|
streamp: Option<TcpStream>,
|
||||||
) -> NodeInfo {
|
) -> NodeInfo {
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
target_name,
|
target_name,
|
||||||
target,
|
target,
|
||||||
port,
|
port,
|
||||||
preference,
|
preference,
|
||||||
stream,
|
streamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_config(
|
pub fn update_config(
|
||||||
&mut self,
|
&mut self,
|
||||||
config_self_mutex: Arc<Mutex<Config>>,
|
config_self_mutex: Arc<Mutex<Config>>,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<()> {
|
||||||
if let Some(ref mut stream) = self.stream {
|
if let Some(ref mut streamp) = self.streamp {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let read_stream = stream.try_clone().unwrap();
|
let read_stream = streamp.try_clone().unwrap();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut reader = BufReader::new(read_stream);
|
let mut reader = BufReader::new(read_stream);
|
||||||
|
|
@ -76,7 +77,7 @@ impl NodeInfo {
|
||||||
// tx.send(response).unwrap_or_default();
|
// tx.send(response).unwrap_or_default();
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.write_all(b"GET CONFIG\n")?;
|
streamp.write_all(b"GET CONFIG\n")?;
|
||||||
|
|
||||||
let s = match rx.recv_timeout(Duration::from_secs(2)) {
|
let s = match rx.recv_timeout(Duration::from_secs(2)) {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
|
|
@ -90,17 +91,14 @@ impl NodeInfo {
|
||||||
};
|
};
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
debug!("Empty response: {:?}", s);
|
debug!("Empty response: {:?}", s);
|
||||||
return Err(Box::new(std::io::Error::new(
|
bail!("No response");
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"No response",
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg: Config = match serde_yaml::from_str(&s) {
|
let cfg: Config = match serde_yaml::from_str(&s) {
|
||||||
Ok(cfg) => cfg,
|
Ok(cfg) => cfg,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Error parsing config: {:?}", e);
|
debug!("Error parsing config: {:?}", e);
|
||||||
return Err(Box::new(e));
|
bail!(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -141,11 +139,8 @@ impl NodeInfo {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("No stream for {}", self.target_name);
|
debug!("No streamp for {}", self.target_name);
|
||||||
Err(Box::new(std::io::Error::new(
|
bail!("No streamp");
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"No stream",
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +165,7 @@ impl NodeConnections {
|
||||||
pub fn get_node_connection(&self, node_name: String) -> Option<Arc<Mutex<NodeInfo>>> {
|
pub fn get_node_connection(&self, node_name: String) -> Option<Arc<Mutex<NodeInfo>>> {
|
||||||
for connection in &self.connections {
|
for connection in &self.connections {
|
||||||
let conn = connection.lock().unwrap();
|
let conn = connection.lock().unwrap();
|
||||||
if conn.target_name == node_name && conn.stream.is_some() {
|
if conn.target_name == node_name && conn.streamp.is_some() {
|
||||||
return Some(connection.clone());
|
return Some(connection.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -207,19 +202,19 @@ impl NodeConnections {
|
||||||
let connection = connection.unwrap();
|
let connection = connection.unwrap();
|
||||||
let connection_guard = connection.lock().unwrap();
|
let connection_guard = connection.lock().unwrap();
|
||||||
|
|
||||||
if connection_guard.stream.is_none() {
|
if connection_guard.streamp.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stream = connection_guard
|
let mut streamp = connection_guard
|
||||||
.stream
|
.streamp
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.try_clone()
|
.try_clone()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let read_stream = stream.try_clone().unwrap();
|
let read_stream = streamp.try_clone().unwrap();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut reader = BufReader::new(read_stream);
|
let mut reader = BufReader::new(read_stream);
|
||||||
|
|
@ -237,9 +232,9 @@ impl NodeConnections {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Write PING
|
// Write PING
|
||||||
let _ = stream.write_all(b"PING\n");
|
let _ = streamp.write_all(b"PING\n");
|
||||||
|
|
||||||
let _ = stream.flush();
|
let _ = streamp.flush();
|
||||||
|
|
||||||
let reply = rx.recv_timeout(Duration::from_secs(2)).unwrap_or_default();
|
let reply = rx.recv_timeout(Duration::from_secs(2)).unwrap_or_default();
|
||||||
if reply == -1 {
|
if reply == -1 {
|
||||||
|
|
@ -250,13 +245,13 @@ impl NodeConnections {
|
||||||
|
|
||||||
pub fn create_node_connection(&mut self, node: &ProviderNode) -> Option<Arc<Mutex<NodeInfo>>> {
|
pub fn create_node_connection(&mut self, node: &ProviderNode) -> Option<Arc<Mutex<NodeInfo>>> {
|
||||||
// TODO: DDNS
|
// TODO: DDNS
|
||||||
let stream = TcpStream::connect_timeout(
|
let streamp = TcpStream::connect_timeout(
|
||||||
&std::net::SocketAddr::new(node.ip.clone().parse().unwrap(), node.port as u16),
|
&std::net::SocketAddr::new(node.ip.clone().parse().unwrap(), node.port as u16),
|
||||||
Duration::from_millis(500),
|
Duration::from_millis(500),
|
||||||
);
|
);
|
||||||
|
|
||||||
match stream {
|
match streamp {
|
||||||
Ok(stream) => {
|
Ok(streamp) => {
|
||||||
let connection = Arc::new(Mutex::new(NodeInfo::new(
|
let connection = Arc::new(Mutex::new(NodeInfo::new(
|
||||||
node.name.clone(),
|
node.name.clone(),
|
||||||
if node.preference == 0 {
|
if node.preference == 0 {
|
||||||
|
|
@ -266,7 +261,7 @@ impl NodeConnections {
|
||||||
},
|
},
|
||||||
node.port,
|
node.port,
|
||||||
node.preference,
|
node.preference,
|
||||||
Some(stream),
|
Some(streamp),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
self.connections.push(connection.clone());
|
self.connections.push(connection.clone());
|
||||||
|
|
@ -275,7 +270,7 @@ impl NodeConnections {
|
||||||
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
if error.kind() != std::io::ErrorKind::ConnectionRefused {
|
if error.kind() != std::io::ErrorKind::ConnectionRefused {
|
||||||
log!("-> Problem creating the stream: {:?}", error);
|
log!("-> Problem creating the streamp: {:?}", error);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -295,17 +290,17 @@ impl NodeConnections {
|
||||||
pub fn confirm(&mut self, source: &str, is_ip: bool) -> Option<String> {
|
pub fn confirm(&mut self, source: &str, is_ip: bool) -> Option<String> {
|
||||||
for connection in &self.connections {
|
for connection in &self.connections {
|
||||||
let conn = connection.lock().unwrap();
|
let conn = connection.lock().unwrap();
|
||||||
if conn.stream.is_none() {
|
if conn.streamp.is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stream = conn.stream.as_ref().unwrap();
|
let mut streamp = conn.streamp.as_ref().unwrap();
|
||||||
stream
|
streamp
|
||||||
.write_all(format!("CONFIRM:{}:{}\n", is_ip as u8, source).as_bytes())
|
.write_all(format!("CONFIRM:{}:{}\n", is_ip as u8, source).as_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let reader = BufReader::new(stream);
|
let reader = BufReader::new(streamp);
|
||||||
// let mut writer = &stream;
|
// let mut writer = &streamp;
|
||||||
|
|
||||||
let sis_ip = is_ip.to_string();
|
let sis_ip = is_ip.to_string();
|
||||||
|
|
||||||
|
|
@ -355,14 +350,14 @@ impl NodeConnections {
|
||||||
) -> Option<ProviderNode> {
|
) -> Option<ProviderNode> {
|
||||||
for connection in &self.connections {
|
for connection in &self.connections {
|
||||||
let conn = connection.lock().unwrap();
|
let conn = connection.lock().unwrap();
|
||||||
if conn.stream.is_none() || conn.target_name != target_name {
|
if conn.streamp.is_none() || conn.target_name != target_name {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stream = conn.stream.as_ref().unwrap();
|
let mut streamp = conn.streamp.as_ref().unwrap();
|
||||||
stream.write_all(b"GET CONFIG\n").unwrap();
|
streamp.write_all(b"GET CONFIG\n").unwrap();
|
||||||
|
|
||||||
let reader = BufReader::new(stream);
|
let reader = BufReader::new(streamp);
|
||||||
|
|
||||||
for line in reader.lines() {
|
for line in reader.lines() {
|
||||||
if line.is_err() {
|
if line.is_err() {
|
||||||
|
|
@ -375,7 +370,7 @@ impl NodeConnections {
|
||||||
let cfg = match parser.parse(None) {
|
let cfg = match parser.parse(None) {
|
||||||
Ok(cfg) => cfg,
|
Ok(cfg) => cfg,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
stream.write_all(b"AUTH FAIL: BAD CONFIG\n").unwrap();
|
streamp.write_all(b"AUTH FAIL: BAD CONFIG\n").unwrap();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -393,12 +388,12 @@ impl NodeConnections {
|
||||||
|
|
||||||
fn is_connection_alive(connection: Arc<Mutex<NodeInfo>>) -> bool {
|
fn is_connection_alive(connection: Arc<Mutex<NodeInfo>>) -> bool {
|
||||||
let connection_guard = connection.lock().unwrap();
|
let connection_guard = connection.lock().unwrap();
|
||||||
if connection_guard.stream.is_none() {
|
if connection_guard.streamp.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut stream = connection_guard.stream.as_ref().unwrap();
|
let mut streamp = connection_guard.streamp.as_ref().unwrap();
|
||||||
match stream.write(&[]) {
|
match streamp.write(&[]) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => true,
|
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => true,
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => false,
|
Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => false,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue