bug fixes

This commit is contained in:
John Smith
2023-06-20 22:18:59 -04:00
parent c78cf5f10c
commit e80a3d3063
7 changed files with 387 additions and 73 deletions

View File

@@ -83,7 +83,7 @@ impl ClientApiConnection {
async fn process_veilid_update(&self, update: json::JsonValue) {
let comproc = self.inner.lock().comproc.clone();
let Some(kind) = update["kind"].as_str() else {
comproc.log_message(format!("missing update kind: {}", update));
comproc.log_message(Level::Error, format!("missing update kind: {}", update));
return;
};
match kind {
@@ -113,7 +113,7 @@ impl ClientApiConnection {
comproc.update_value_change(&update);
}
_ => {
comproc.log_message(format!("unknown update kind: {}", update));
comproc.log_message(Level::Error, format!("unknown update kind: {}", update));
}
}
}

View File

@@ -105,6 +105,7 @@ impl CommandProcessor {
pub fn cmd_help(&self, _rest: Option<String>, callback: UICallback) -> Result<(), String> {
trace!("CommandProcessor::cmd_help");
self.ui_sender().add_node_event(
Level::Info,
r#"Commands:
exit/quit - exit the client
disconnect - disconnect the client from the Veilid node
@@ -206,7 +207,7 @@ reply - reply to an AppCall not handled directly by the server
let log_level = match convert_loglevel(&rest.unwrap_or_default()) {
Ok(v) => v,
Err(e) => {
ui.add_node_event(format!("Failed to change log level: {}", e));
ui.add_node_event(Level::Error, format!("Failed to change log level: {}", e));
ui.send_callback(callback);
return;
}
@@ -239,7 +240,7 @@ reply - reply to an AppCall not handled directly by the server
let (id, msg) = if let Some(second) = second {
let id = match u64::from_str(&first) {
Err(e) => {
ui.add_node_event(format!("invalid appcall id: {}", e));
ui.add_node_event(Level::Error, format!("invalid appcall id: {}", e));
ui.send_callback(callback);
return;
}
@@ -249,7 +250,7 @@ reply - reply to an AppCall not handled directly by the server
} else {
let id = match some_last_id {
None => {
ui.add_node_event("must specify last call id".to_owned());
ui.add_node_event(Level::Error, "must specify last call id".to_owned());
ui.send_callback(callback);
return;
}
@@ -260,7 +261,7 @@ reply - reply to an AppCall not handled directly by the server
let msg = if msg[0..1] == "#".to_owned() {
match hex::decode(msg[1..].as_bytes().to_vec()) {
Err(e) => {
ui.add_node_event(format!("invalid hex message: {}", e));
ui.add_node_event(Level::Error, format!("invalid hex message: {}", e));
ui.send_callback(callback);
return;
}
@@ -272,7 +273,10 @@ reply - reply to an AppCall not handled directly by the server
let msglen = msg.len();
match capi.server_appcall_reply(id, msg).await {
Ok(()) => {
ui.add_node_event(format!("reply sent to {} : {} bytes", id, msglen));
ui.add_node_event(
Level::Info,
format!("reply sent to {} : {} bytes", id, msglen),
);
ui.send_callback(callback);
return;
}
@@ -383,8 +387,8 @@ reply - reply to an AppCall not handled directly by the server
// calls into ui
////////////////////////////////////////////
pub fn log_message(&self, message: String) {
self.inner().ui_sender.add_node_event(message);
pub fn log_message(&self, log_level: Level, message: String) {
self.inner().ui_sender.add_node_event(log_level, message);
}
pub fn update_attachment(&self, attachment: &json::JsonValue) {
@@ -428,25 +432,30 @@ reply - reply to an AppCall not handled directly by the server
));
}
if !out.is_empty() {
self.inner().ui_sender.add_node_event(out);
self.inner().ui_sender.add_node_event(Level::Info, out);
}
}
pub fn update_value_change(&self, value_change: &json::JsonValue) {
let out = format!("Value change: {:?}", value_change.as_str().unwrap_or("???"));
self.inner().ui_sender.add_node_event(out);
self.inner().ui_sender.add_node_event(Level::Info, out);
}
pub fn update_log(&self, log: &json::JsonValue) {
self.inner().ui_sender.add_node_event(format!(
"{}: {}{}",
log["log_level"].as_str().unwrap_or("???"),
log["message"].as_str().unwrap_or("???"),
if let Some(bt) = log["backtrace"].as_str() {
format!("\nBacktrace:\n{}", bt)
} else {
"".to_owned()
}
));
let log_level =
Level::from_str(log["log_level"].as_str().unwrap_or("error")).unwrap_or(Level::Error);
self.inner().ui_sender.add_node_event(
log_level,
format!(
"{}: {}{}",
log["log_level"].as_str().unwrap_or("???"),
log["message"].as_str().unwrap_or("???"),
if let Some(bt) = log["backtrace"].as_str() {
format!("\nBacktrace:\n{}", bt)
} else {
"".to_owned()
}
),
);
}
pub fn update_app_message(&self, msg: &json::JsonValue) {
@@ -466,9 +475,10 @@ reply - reply to an AppCall not handled directly by the server
hex::encode(message)
};
self.inner()
.ui_sender
.add_node_event(format!("AppMessage ({:?}): {}", msg["sender"], strmsg));
self.inner().ui_sender.add_node_event(
Level::Info,
format!("AppMessage ({:?}): {}", msg["sender"], strmsg),
);
}
pub fn update_app_call(&self, call: &json::JsonValue) {
@@ -490,10 +500,13 @@ reply - reply to an AppCall not handled directly by the server
let id = json_str_u64(&call["call_id"]);
self.inner().ui_sender.add_node_event(format!(
"AppCall ({:?}) id = {:016x} : {}",
call["sender"], id, strmsg
));
self.inner().ui_sender.add_node_event(
Level::Info,
format!(
"AppCall ({:?}) id = {:016x} : {}",
call["sender"], id, strmsg
),
);
self.inner_mut().last_call_id = Some(id);
}

View File

@@ -74,8 +74,14 @@ impl TableViewItem<PeerTableColumn> for json::JsonValue {
Self: Sized,
{
match column {
PeerTableColumn::NodeId => self.to_column(column).cmp(&other.to_column(column)),
PeerTableColumn::Address => self.to_column(column).cmp(&other.to_column(column)),
PeerTableColumn::NodeId => self
.to_column(column)
.to_ascii_lowercase()
.cmp(&other.to_column(column).to_ascii_lowercase()),
PeerTableColumn::Address => self
.to_column(column)
.to_ascii_lowercase()
.cmp(&other.to_column(column).to_ascii_lowercase()),
PeerTableColumn::LatencyAvg => json_str_u64(&self["peer_stats"]["latency"]["average"])
.cmp(&json_str_u64(&other["peer_stats"]["latency"]["average"])),
PeerTableColumn::TransferDownAvg => {

View File

@@ -27,23 +27,23 @@ interface:
shadow: false
borders: "simple"
colors:
background : "#333D3D"
shadow : "#000000"
view : "#1c2323"
primary : "#a6d8d3"
secondary : "#8cb4b7"
tertiary : "#eeeeee"
title_primary : "#f93fbd"
title_secondary : "#ff0000"
highlight : "#f93fbd"
highlight_inactive : "#a6d8d3"
highlight_text : "#333333"
background : "black"
shadow : "black"
view : "black"
primary : "light cyan"
secondary : "cyan"
tertiary : "green"
title_primary : "light magenta"
title_secondary : "magenta"
highlight : "light white"
highlight_inactive : "white"
highlight_text : "black"
log_colors:
trace : "#707070"
debug : "#a0a0a0"
info : "#5cd3c6"
warn : "#fedc50"
error : "#ff4a15"
trace : "light blue"
debug : "light green"
info : "white"
warn : "light yellow"
error : "light red"
"###
.replace(
"%LOGGING_FILE_DIRECTORY%",

View File

@@ -12,7 +12,7 @@ use cursive::views::*;
use cursive::Cursive;
use cursive::CursiveRunnable;
use cursive_flexi_logger_view::{CursiveLogWriter, FlexiLoggerView};
//use cursive_multiplex::*;
// use cursive_multiplex::*;
use std::collections::{HashMap, VecDeque};
use thiserror::Error;
@@ -311,8 +311,7 @@ impl UI {
.button("Close", move |s| {
s.pop_layer();
close_cb(s);
}), //.wrap_with(CircularFocus::new)
//.wrap_tab(),
}),
);
s.set_global_callback(cursive::event::Event::Key(Key::Esc), move |s| {
s.set_global_callback(cursive::event::Event::Key(Key::Esc), UI::quit_handler);
@@ -455,6 +454,23 @@ impl UI {
Self::command_processor(s).start_connection();
}
fn on_submit_peers_table_view(s: &mut Cursive, _row: usize, index: usize) {
let peers_table_view = UI::peers(s);
let node_id = peers_table_view
.borrow_item(index)
.map(|j| j["node_ids"][0].to_string());
if let Some(node_id) = node_id {
let mut clipboard = arboard::Clipboard::new().unwrap();
clipboard.set_text(node_id.clone()).unwrap();
let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap();
cursive_flexi_logger_view::push_to_log(StyledString::styled(
format!(">> NodeId Copied: {}", node_id),
color,
));
}
}
fn show_connection_dialog(s: &mut Cursive, state: ConnectionState) -> bool {
let mut inner = Self::inner_mut(s);
@@ -644,7 +660,28 @@ impl UI {
fn refresh_peers(s: &mut Cursive) {
let mut peers = UI::peers(s);
let inner = Self::inner_mut(s);
let sel_item = peers.item();
let sel_item_text = peers
.item()
.map(|x| peers.borrow_items()[x]["node_ids"][0].clone());
peers.set_items_stable(inner.ui_state.peers_state.get().clone());
let mut selected = false;
if let Some(sel_item_text) = sel_item_text {
// First select by name
for n in 0..peers.borrow_items().len() {
if peers.borrow_items()[n]["node_ids"][0] == sel_item_text {
peers.set_selected_item(n);
selected = true;
}
}
}
if !selected {
if let Some(sel_item) = sel_item {
peers.set_selected_item(sel_item);
}
}
}
fn update_cb(s: &mut Cursive) {
@@ -707,9 +744,6 @@ impl UI {
// Instantiate the cursive runnable
let runnable = CursiveRunnable::new(
|| -> Result<Box<dyn cursive::backend::Backend>, Box<DumbError>> {
#[cfg(feature = "macos")]
let backend = cursive::backends::curses::n::Backend::init().unwrap();
#[cfg(not(feature = "macos"))]
let backend = cursive::backends::crossterm::Backend::init().unwrap();
let buffered_backend = cursive_buffered_backend::BufferedBackend::new(backend);
Ok(Box::new(buffered_backend))
@@ -737,6 +771,11 @@ impl UI {
})),
};
let ui_sender = UISender {
inner: this.inner.clone(),
cb_sink,
};
let mut inner = this.inner.lock();
// Make the inner object accessible in callbacks easily
@@ -750,12 +789,14 @@ impl UI {
.with_name("node-events-panel")
.full_screen();
let peers_table_view = PeersTableView::new()
let mut peers_table_view = PeersTableView::new()
.column(PeerTableColumn::NodeId, "Node Id", |c| c.width(48))
.column(PeerTableColumn::Address, "Address", |c| c)
.column(PeerTableColumn::LatencyAvg, "Ping", |c| c.width(8))
.column(PeerTableColumn::TransferDownAvg, "Down", |c| c.width(8))
.column(PeerTableColumn::TransferUpAvg, "Up", |c| c.width(8))
.column(PeerTableColumn::TransferUpAvg, "Up", |c| c.width(8));
peers_table_view.set_on_submit(UI::on_submit_peers_table_view);
let peers_table_view = peers_table_view
.with_name("peers")
.full_width()
.min_height(8);
@@ -832,8 +873,7 @@ impl UI {
drop(inner);
let inner = this.inner.clone();
(this, UISender { inner, cb_sink })
(this, ui_sender)
}
pub fn cursive_flexi_logger(&self) -> Box<CursiveLogWriter> {
let mut flv = cursive_flexi_logger_view::cursive_flexi_logger(self.siv.cb_sink().clone());
@@ -906,7 +946,7 @@ impl UISender {
started: bool,
bps_down: u64,
bps_up: u64,
peers: Vec<json::JsonValue>,
mut peers: Vec<json::JsonValue>,
) {
{
let mut inner = self.inner.lock();
@@ -915,6 +955,11 @@ impl UISender {
((bps_down as f64) / 1000.0f64) as f32,
((bps_up as f64) / 1000.0f64) as f32,
));
peers.sort_by(|a, b| {
a["node_ids"][0]
.to_string()
.cmp(&b["node_ids"][0].to_string())
});
inner.ui_state.peers_state.set(peers);
}
let _ = self.cb_sink.send(Box::new(UI::update_cb));
@@ -935,10 +980,10 @@ impl UISender {
let _ = self.cb_sink.send(Box::new(UI::update_cb));
}
pub fn add_node_event(&self, event: String) {
pub fn add_node_event(&self, log_color: Level, event: String) {
{
let inner = self.inner.lock();
let color = *inner.log_colors.get(&Level::Info).unwrap();
let color = *inner.log_colors.get(&log_color).unwrap();
let mut starting_style: Style = color.into();
for line in event.lines() {
let (spanned_string, end_style) =