fixes for stats and crash

This commit is contained in:
John Smith 2022-05-18 10:17:04 -04:00
parent 1326424eae
commit f4f5808df2
9 changed files with 92 additions and 20 deletions

7
.vscode/launch.json vendored
View File

@ -11,6 +11,13 @@
"program": "${workspaceFolder}/target/debug/veilid-server", "program": "${workspaceFolder}/target/debug/veilid-server",
"pid": "${command:pickMyProcess}" "pid": "${command:pickMyProcess}"
}, },
{
"type": "lldb",
"request": "attach",
"name": "Attach to veilid-cli",
"program": "${workspaceFolder}/target/debug/veilid-cli",
"pid": "${command:pickMyProcess}"
},
{ {
"type": "lldb", "type": "lldb",
"request": "attach", "request": "attach",

View File

@ -9,6 +9,14 @@ use std::net::SocketAddr;
use std::rc::Rc; use std::rc::Rc;
use veilid_core::xx::*; use veilid_core::xx::*;
macro_rules! capnp_failed {
($ex:expr) => {{
let msg = format!("Capnp Error: {}", $ex);
error!("{}", msg);
Promise::err(capnp::Error::failed(msg))
}};
}
struct VeilidClientImpl { struct VeilidClientImpl {
comproc: CommandProcessor, comproc: CommandProcessor,
} }
@ -30,7 +38,7 @@ impl veilid_client::Server for VeilidClientImpl {
let which = match veilid_update.which() { let which = match veilid_update.which() {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
panic!("(missing update kind in schema: {:?})", e); return capnp_failed!(format!("(missing update kind in schema: {:?})", e));
} }
}; };
match which { match which {
@ -40,8 +48,28 @@ impl veilid_client::Server for VeilidClientImpl {
trace!("Attachment: {}", state as u16); trace!("Attachment: {}", state as u16);
self.comproc.update_attachment(state); self.comproc.update_attachment(state);
} }
_ => { veilid_update::Attachment(Err(e)) => {
panic!("shouldn't get this") return capnp_failed!(format!("Update Attachment Error: {}", e));
}
veilid_update::Network(Ok(network)) => {
let started = network.get_started();
let bps_down = network.get_bps_down();
let bps_up = network.get_bps_up();
trace!(
"Network: started: {} bps_down: {} bps_up: {}",
started,
bps_down,
bps_up
);
self.comproc
.update_network_status(started, bps_down, bps_up);
}
veilid_update::Network(Err(e)) => {
return capnp_failed!(format!("Update Network Error: {}", e));
}
veilid_update::Shutdown(()) => {
return capnp_failed!("Should not get Shutdown here".to_owned());
} }
} }

View File

@ -351,6 +351,12 @@ impl NetworkManager {
self.send_network_update(); self.send_network_update();
} }
// Run the rolling transfers task
self.unlocked_inner.rolling_transfers_task.tick().await?;
// Run the relay management task
self.unlocked_inner.relay_management_task.tick().await?;
// Run the routing table tick // Run the routing table tick
routing_table.tick().await?; routing_table.tick().await?;

View File

@ -10,7 +10,7 @@ const ROLLING_LATENCIES_SIZE: usize = 10;
// - Size is number of entries // - Size is number of entries
// - Interval is number of seconds in each entry // - Interval is number of seconds in each entry
const ROLLING_TRANSFERS_SIZE: usize = 10; const ROLLING_TRANSFERS_SIZE: usize = 10;
pub const ROLLING_TRANSFERS_INTERVAL_SECS: u32 = 10; pub const ROLLING_TRANSFERS_INTERVAL_SECS: u32 = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct TransferCount { pub struct TransferCount {
@ -71,7 +71,7 @@ impl TransferStatsAccounting {
transfer_stats.down.minimum.min_assign(bpsd); transfer_stats.down.minimum.min_assign(bpsd);
transfer_stats.up.minimum.min_assign(bpsu); transfer_stats.up.minimum.min_assign(bpsu);
transfer_stats.down.average += bpsd; transfer_stats.down.average += bpsd;
transfer_stats.down.average += bpsu; transfer_stats.up.average += bpsu;
} }
let len = self.rolling_transfers.len() as u64; let len = self.rolling_transfers.len() as u64;
transfer_stats.down.average /= len; transfer_stats.down.average /= len;

View File

@ -3,7 +3,7 @@ use super::*;
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord)] #[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord)]
pub enum RPCError { pub enum RPCError {
Timeout, Timeout,
InvalidFormat, InvalidFormat(String),
Unreachable(DHTKey), Unreachable(DHTKey),
Unimplemented(String), Unimplemented(String),
Protocol(String), Protocol(String),
@ -14,6 +14,10 @@ pub fn rpc_error_internal<T: AsRef<str>>(x: T) -> RPCError {
error!("RPCError Internal: {}", x.as_ref()); error!("RPCError Internal: {}", x.as_ref());
RPCError::Internal(x.as_ref().to_owned()) RPCError::Internal(x.as_ref().to_owned())
} }
pub fn rpc_error_invalid_format<T: AsRef<str>>(x: T) -> RPCError {
error!("RPCError Invalid Format: {}", x.as_ref());
RPCError::InvalidFormat(x.as_ref().to_owned())
}
pub fn rpc_error_protocol<T: AsRef<str>>(x: T) -> RPCError { pub fn rpc_error_protocol<T: AsRef<str>>(x: T) -> RPCError {
error!("RPCError Protocol: {}", x.as_ref()); error!("RPCError Protocol: {}", x.as_ref());
RPCError::Protocol(x.as_ref().to_owned()) RPCError::Protocol(x.as_ref().to_owned())
@ -35,7 +39,7 @@ impl fmt::Display for RPCError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
RPCError::Timeout => write!(f, "[RPCError: Timeout]"), RPCError::Timeout => write!(f, "[RPCError: Timeout]"),
RPCError::InvalidFormat => write!(f, "[RPCError: InvalidFormat]"), RPCError::InvalidFormat(s) => write!(f, "[RPCError: InvalidFormat({})]", s),
RPCError::Unreachable(k) => write!(f, "[RPCError: Unreachable({})]", k), RPCError::Unreachable(k) => write!(f, "[RPCError: Unreachable({})]", k),
RPCError::Unimplemented(s) => write!(f, "[RPCError: Unimplemented({})]", s), RPCError::Unimplemented(s) => write!(f, "[RPCError: Unimplemented({})]", s),
RPCError::Protocol(s) => write!(f, "[RPCError: Protocol({})]", s), RPCError::Protocol(s) => write!(f, "[RPCError: Protocol({})]", s),

View File

@ -855,7 +855,9 @@ impl RPCProcessor {
// This should never want an answer // This should never want an answer
if self.wants_answer(&operation)? { if self.wants_answer(&operation)? {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"validate dial info should not want answer",
));
} }
// get validateDialInfo reader // get validateDialInfo reader
@ -958,7 +960,7 @@ impl RPCProcessor {
// find_node must always want an answer // find_node must always want an answer
if !self.wants_answer(&operation)? { if !self.wants_answer(&operation)? {
return Err(RPCError::InvalidFormat).map_err(logthru_rpc!()); return Err(rpc_error_invalid_format("find_node_q should want answer"));
} }
// get findNodeQ reader // get findNodeQ reader
@ -1030,7 +1032,9 @@ impl RPCProcessor {
// This should never want an answer // This should never want an answer
if self.wants_answer(&operation)? { if self.wants_answer(&operation)? {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"node_info_update should not want answer",
));
} }
// get nodeInfoUpdate reader // get nodeInfoUpdate reader
@ -1048,7 +1052,9 @@ impl RPCProcessor {
// Update our routing table with signed node info // Update our routing table with signed node info
if !self.filter_peer_scope(&signed_node_info.node_info) { if !self.filter_peer_scope(&signed_node_info.node_info) {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"node_info_update has invalid peer scope",
));
} }
let _ = self let _ = self
.routing_table() .routing_table()
@ -1092,7 +1098,7 @@ impl RPCProcessor {
// This should never want an answer // This should never want an answer
if self.wants_answer(&operation)? { if self.wants_answer(&operation)? {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format("signal should not want answer"));
} }
// get signal reader // get signal reader
@ -1123,7 +1129,9 @@ impl RPCProcessor {
// This should never want an answer // This should never want an answer
if self.wants_answer(&operation)? { if self.wants_answer(&operation)? {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"return receipt should not want answer",
));
} }
// get returnReceipt reader // get returnReceipt reader
@ -1229,7 +1237,9 @@ impl RPCProcessor {
{ {
// Sender NodeInfo was specified, update our routing table with it // Sender NodeInfo was specified, update our routing table with it
if !self.filter_peer_scope(&sender_ni.node_info) { if !self.filter_peer_scope(&sender_ni.node_info) {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"respond_to_sender_signed_node_info has invalid peer scope",
));
} }
let nr = self let nr = self
.routing_table() .routing_table()
@ -1630,7 +1640,9 @@ impl RPCProcessor {
let peer_info = decode_peer_info(&p, true)?; let peer_info = decode_peer_info(&p, true)?;
if !self.filter_peer_scope(&peer_info.signed_node_info.node_info) { if !self.filter_peer_scope(&peer_info.signed_node_info.node_info) {
return Err(RPCError::InvalidFormat); return Err(rpc_error_invalid_format(
"find_node response has invalid peer scope",
));
} }
peers.push(peer_info); peers.push(peer_info);

View File

@ -123,8 +123,8 @@ fn convert_rpc_error(x: RPCError) -> VeilidAPIError {
RPCError::Unimplemented(s) => VeilidAPIError::Unimplemented { message: s }, RPCError::Unimplemented(s) => VeilidAPIError::Unimplemented { message: s },
RPCError::Internal(s) => VeilidAPIError::Internal { message: s }, RPCError::Internal(s) => VeilidAPIError::Internal { message: s },
RPCError::Protocol(s) => VeilidAPIError::Internal { message: s }, RPCError::Protocol(s) => VeilidAPIError::Internal { message: s },
RPCError::InvalidFormat => VeilidAPIError::Internal { RPCError::InvalidFormat(s) => VeilidAPIError::Internal {
message: "Invalid packet format".to_owned(), message: format!("Invalid RPC format: {}", s),
}, },
} }
} }

View File

@ -16,6 +16,13 @@ fn do_clap_matches(default_config_path: &OsStr) -> Result<clap::ArgMatches, clap
.short('d') .short('d')
.help("Run in daemon mode in the background"), .help("Run in daemon mode in the background"),
) )
.arg(
Arg::new("foreground")
.long("foreground")
.short('f')
.conflicts_with("daemon")
.help("Run in the foreground"),
)
.arg( .arg(
Arg::new("config-file") Arg::new("config-file")
.short('c') .short('c')
@ -155,6 +162,9 @@ pub fn process_command_line() -> Result<(Settings, ArgMatches), String> {
settingsrw.daemon.enabled = true; settingsrw.daemon.enabled = true;
settingsrw.logging.terminal.enabled = false; settingsrw.logging.terminal.enabled = false;
} }
if matches.occurrences_of("foreground") != 0 {
settingsrw.daemon.enabled = false;
}
if matches.occurrences_of("subnode-index") != 0 { if matches.occurrences_of("subnode-index") != 0 {
let subnode_index = match matches.value_of("subnode-index") { let subnode_index = match matches.value_of("subnode-index") {
Some(x) => x Some(x) => x
@ -219,7 +229,7 @@ pub fn process_command_line() -> Result<(Settings, ArgMatches), String> {
} }
if matches.occurrences_of("bootstrap") != 0 { if matches.occurrences_of("bootstrap") != 0 {
let bootstrap_list = match matches.value_of("bootstrap-list") { let bootstrap_list = match matches.value_of("bootstrap") {
Some(x) => { Some(x) => {
println!("Overriding bootstrap list with: "); println!("Overriding bootstrap list with: ");
let mut out: Vec<String> = Vec::new(); let mut out: Vec<String> = Vec::new();
@ -231,14 +241,14 @@ pub fn process_command_line() -> Result<(Settings, ArgMatches), String> {
out out
} }
None => { None => {
return Err("value not specified for bootstrap list".to_owned()); return Err("value not specified for bootstrap".to_owned());
} }
}; };
settingsrw.core.network.bootstrap = bootstrap_list; settingsrw.core.network.bootstrap = bootstrap_list;
} }
if matches.occurrences_of("bootstrap-nodes") != 0 { if matches.occurrences_of("bootstrap-nodes") != 0 {
let bootstrap_list = match matches.value_of("bootstrap-list") { let bootstrap_list = match matches.value_of("bootstrap-nodes") {
Some(x) => { Some(x) => {
println!("Overriding bootstrap node list with: "); println!("Overriding bootstrap node list with: ");
let mut out: Vec<ParsedNodeDialInfo> = Vec::new(); let mut out: Vec<ParsedNodeDialInfo> = Vec::new();

View File

@ -159,6 +159,11 @@ pub async fn run_veilid_server(
shutdown(); shutdown();
} }
// Process shutdown-immediate
if matches!(server_mode, ServerMode::ShutdownImmediate) {
shutdown();
}
// Idle while waiting to exit // Idle while waiting to exit
let shutdown_switch = { let shutdown_switch = {
let shutdown_switch_locked = SHUTDOWN_SWITCH.lock(); let shutdown_switch_locked = SHUTDOWN_SWITCH.lock();