Просмотр исходного кода

dnetview: various bug fixes and cleanup

* fix bug that was multiplying the number of inbound and outbounds due to including null() sessions in a loop
* stop looping through session.info in make_ordered_list (it's not a vew now)
* create a specific networkID for lilith networks (better debugging)
* rename Connect to Slot
lunar-mining 3 лет назад
Родитель
Сommit
526a4c7e77
4 измененных файлов с 161 добавлено и 164 удалено
  1. 5 3
      bin/dnetview/src/model.rs
  2. 103 94
      bin/dnetview/src/parser.rs
  3. 20 14
      bin/dnetview/src/util.rs
  4. 33 53
      bin/dnetview/src/view.rs

+ 5 - 3
bin/dnetview/src/model.rs

@@ -29,7 +29,7 @@ type MsgMap = Mutex<HashMap<String, MsgLog>>;
 pub enum Session {
     Inbound,
     Outbound,
-    Manual,
+    //Manual,
     Offline,
 }
 
@@ -39,7 +39,7 @@ pub enum SelectableObject {
     Lilith(LilithInfo),
     Network(NetworkInfo),
     Session(SessionInfo),
-    Connect(SlotInfo),
+    Slot(SlotInfo),
 }
 
 #[derive(Debug)]
@@ -88,6 +88,7 @@ pub struct SessionInfo {
     pub addr: String,
     pub state: Option<String>,
     pub info: SlotInfo,
+    pub sort: Session,
     pub is_empty: bool,
 }
 
@@ -98,9 +99,10 @@ impl SessionInfo {
         addr: String,
         state: Option<String>,
         info: SlotInfo,
+        sort: Session,
         is_empty: bool,
     ) -> Self {
-        Self { dnet_id, node_id, addr, state, info, is_empty }
+        Self { dnet_id, node_id, addr, state, info, sort, is_empty }
     }
 }
 

+ 103 - 94
bin/dnetview/src/parser.rs

@@ -33,7 +33,7 @@ use crate::{
         LilithInfo, Model, NetworkInfo, NodeInfo, SelectableObject, Session, SessionInfo, SlotInfo,
     },
     rpc::RpcConnect,
-    util::{make_empty_id, make_info_id, make_node_id, make_session_id},
+    util::{make_empty_id, make_info_id, make_network_id, make_node_id, make_session_id},
 };
 
 pub struct DataParser {
@@ -93,7 +93,6 @@ impl DataParser {
             // Parse response
             match response {
                 Ok(reply) => {
-                    debug!("dnetview:: poll() reply {:?}", reply);
                     if reply.as_object().is_none() || reply.as_object().unwrap().is_empty() {
                         return Err(DnetViewError::EmptyRpcReply)
                     }
@@ -121,13 +120,13 @@ impl DataParser {
     async fn parse_offline(&self, node_name: String) -> DnetViewResult<()> {
         debug!(target: "dnetview", "parse_offline() START");
         let name = "Offline".to_string();
-        let session_type = Session::Offline;
+        let sort = Session::Offline;
 
         let mut sessions: Vec<SessionInfo> = Vec::new();
         let hosts = Vec::new();
 
         let node_id = make_node_id(&node_name)?;
-        let dnet_id = make_empty_id(&node_id, &session_type, 0)?;
+        let dnet_id = make_empty_id(&node_id, &sort, 0)?;
         let addr = "Null".to_string();
         let state = None;
         let random_id = 0;
@@ -148,10 +147,10 @@ impl DataParser {
         let session_info = SessionInfo::new(
             dnet_id,
             node_id.clone(),
-            //name.clone(),
             addr.clone(),
             state,
             slot,
+            sort.clone(),
             is_empty,
         );
         sessions.push(session_info);
@@ -204,7 +203,7 @@ impl DataParser {
         let mut networks = vec![];
         for spawn in spawns {
             let name = spawn.get("name").unwrap().as_str().unwrap().to_string();
-            let id = make_node_id(&name)?;
+            let id = make_network_id(&name)?;
             let urls: Vec<String> =
                 serde_json::from_value(spawn.get("urls").unwrap().clone()).unwrap();
             let nodes: Vec<String> =
@@ -293,7 +292,7 @@ impl DataParser {
                         .lock()
                         .await
                         .insert(inbound.clone().dnet_id, inbound_obj.clone());
-                    let info_obj = SelectableObject::Connect(inbound.info.clone());
+                    let info_obj = SelectableObject::Slot(inbound.info.clone());
                     self.model
                         .selectables
                         .lock()
@@ -309,7 +308,7 @@ impl DataParser {
                         .lock()
                         .await
                         .insert(outbound.clone().dnet_id, outbound_obj.clone());
-                    let info_obj = SelectableObject::Connect(outbound.info.clone());
+                    let info_obj = SelectableObject::Slot(outbound.info.clone());
                     self.model
                         .selectables
                         .lock()
@@ -325,9 +324,9 @@ impl DataParser {
         &self,
         reply: &Value,
         node_id: &String,
-        prefix: Session,
+        sort: Session,
     ) -> DnetViewResult<Vec<SessionInfo>> {
-        let session_id = make_session_id(&node_id, &prefix)?;
+        let session_id = make_session_id(&node_id, &sort)?;
         let mut session_info: Vec<SessionInfo> = Vec::new();
 
         // TODO: improve this ugly hack.
@@ -335,15 +334,14 @@ impl DataParser {
 
         // Dnetview is not enabled.
         if reply.is_null() {
-            debug!(target: "dnetview", "parse_outbound() reply.is_null() == True");
             slot_count += 1;
-            let info_id = make_empty_id(&node_id, &prefix, slot_count)?;
+            let info_id = make_empty_id(&node_id, &sort, slot_count)?;
             let node_id = node_id.to_string();
             let addr = "Null".to_string();
             let random_id = 0;
             let remote_id = "Null".to_string();
             let log = Vec::new();
-            let is_empty = false;
+            let is_empty = true;
 
             let slot = SlotInfo::new(
                 info_id.clone(),
@@ -358,94 +356,106 @@ impl DataParser {
 
             let addr = "Null".to_string();
             let state = None;
-            let session =
-                SessionInfo::new(session_id.clone(), node_id.clone(), addr, state, slot, is_empty);
+            let session = SessionInfo::new(
+                session_id.clone(),
+                node_id.clone(),
+                addr,
+                state,
+                slot,
+                sort.clone(),
+                is_empty,
+            );
             session_info.push(session);
 
             return Ok(session_info)
         }
 
         let sessions = reply.as_array().unwrap();
-        debug!(target: "dnetview", "parse_outbound() len session{:?}", sessions.len());
 
         for session in sessions {
-            match session.as_object() {
-                Some(obj) => {
-                    debug!(target: "dnetview", "parse_outbound() obj {:?}", session);
-                    let addr = obj.get("addr").unwrap().as_str().unwrap().to_string();
-
-                    let state: Option<String> = match obj.get("state") {
-                        Some(state) => Some(state.as_str().unwrap().to_string()),
-                        None => None,
-                    };
-
-                    let info: serde_json::Map<String, Value> =
-                        serde_json::from_value(obj.get("info").unwrap().clone()).unwrap();
-
-                    let slot_addr = info.get("addr").unwrap().as_str().unwrap().to_string();
-                    let random_id = info.get("random_id").unwrap().as_u64().unwrap();
-                    let remote_id = info.get("remote_id").unwrap().as_str().unwrap().to_string();
-                    let info_id = make_info_id(&random_id)?;
-
-                    let log: Vec<(NanoTimestamp, String, String)> =
-                        serde_json::from_value(info.get("log").unwrap().clone()).unwrap();
-
-                    // ...
-                    let node_id = node_id.to_string();
-                    let is_empty = false;
-
-                    let slot = SlotInfo::new(
-                        info_id.clone(),
-                        node_id.clone(),
-                        slot_addr,
-                        random_id,
-                        remote_id,
-                        log,
-                        is_empty,
-                    );
-
-                    let session = SessionInfo::new(
-                        session_id.clone(),
-                        node_id.clone(),
-                        addr.clone(),
-                        state,
-                        slot,
-                        is_empty,
-                    );
-                    session_info.push(session);
-                }
-                None => {
-                    // TODO: clean up empty info boilerplate.
-                    slot_count += 1;
-                    let info_id = make_empty_id(node_id, &prefix, slot_count)?;
-                    let node_id = node_id.to_string();
-                    let addr = "Null".to_string();
-                    let random_id = 0;
-                    let remote_id = "Null".to_string();
-                    let log = Vec::new();
-                    let is_empty = true;
-
-                    let slot = SlotInfo::new(
-                        info_id.clone(),
-                        node_id.clone(),
-                        addr.clone(),
-                        random_id,
-                        remote_id,
-                        log,
-                        is_empty,
-                    );
-                    let is_empty = true;
-
-                    let state = None;
-                    let session = SessionInfo::new(
-                        session_id.clone(),
-                        node_id.clone(),
-                        addr.clone(),
-                        state,
-                        slot,
-                        is_empty,
-                    );
-                    session_info.push(session);
+            // TODO: display empty sessions?
+            if !session.is_null() {
+                match session.as_object() {
+                    Some(obj) => {
+                        debug!(target: "dnetview", "parse_outbound() OBJ {:?}", obj);
+                        let addr = obj.get("addr").unwrap().as_str().unwrap().to_string();
+
+                        let state: Option<String> = match obj.get("state") {
+                            Some(state) => Some(state.as_str().unwrap().to_string()),
+                            None => None,
+                        };
+
+                        let info: serde_json::Map<String, Value> =
+                            serde_json::from_value(obj.get("info").unwrap().clone()).unwrap();
+
+                        let slot_addr = info.get("addr").unwrap().as_str().unwrap().to_string();
+                        let random_id = info.get("random_id").unwrap().as_u64().unwrap();
+                        let remote_id =
+                            info.get("remote_id").unwrap().as_str().unwrap().to_string();
+                        let info_id = make_info_id(&random_id)?;
+
+                        let log: Vec<(NanoTimestamp, String, String)> =
+                            serde_json::from_value(info.get("log").unwrap().clone()).unwrap();
+
+                        // ...
+                        let node_id = node_id.to_string();
+                        let is_empty = false;
+
+                        let slot = SlotInfo::new(
+                            info_id.clone(),
+                            node_id.clone(),
+                            slot_addr,
+                            random_id,
+                            remote_id,
+                            log,
+                            is_empty,
+                        );
+
+                        let session = SessionInfo::new(
+                            session_id.clone(),
+                            node_id.clone(),
+                            addr.clone(),
+                            state,
+                            slot.clone(),
+                            sort.clone(),
+                            is_empty,
+                        );
+                        session_info.push(session);
+                    }
+                    None => {
+                        // TODO: clean up empty info boilerplate.
+                        slot_count += 1;
+                        let info_id = make_empty_id(node_id, &sort, slot_count)?;
+                        let node_id = node_id.to_string();
+                        let addr = "Null".to_string();
+                        let random_id = 0;
+                        let remote_id = "Null".to_string();
+                        let log = Vec::new();
+                        let is_empty = true;
+
+                        let slot = SlotInfo::new(
+                            info_id.clone(),
+                            node_id.clone(),
+                            addr.clone(),
+                            random_id,
+                            remote_id,
+                            log,
+                            is_empty,
+                        );
+                        let is_empty = true;
+
+                        let state = None;
+                        let session = SessionInfo::new(
+                            session_id.clone(),
+                            node_id.clone(),
+                            addr.clone(),
+                            state,
+                            slot.clone(),
+                            sort.clone(),
+                            is_empty,
+                        );
+                        session_info.push(session);
+                    }
                 }
             }
         }
@@ -470,7 +480,6 @@ impl DataParser {
                     let h = Vec::new();
                     return Ok(h)
                 }
-                debug!("dnetview::parse_hosts() hosts returns None and !is_null() {}", hosts);
                 Err(DnetViewError::ValueIsNotObject)
             }
         }

+ 20 - 14
bin/dnetview/src/util.rs

@@ -26,13 +26,19 @@ pub fn make_node_id(node_name: &String) -> Result<String> {
     Ok(id)
 }
 
+pub fn make_network_id(node_name: &String) -> Result<String> {
+    let mut id = hex::encode(node_name);
+    id.insert_str(0, "NETWORK");
+    Ok(id)
+}
+
 pub fn make_session_id(node_id: &str, session: &Session) -> Result<String> {
     let mut num = 0_u64;
 
     let session_chars = match session {
         Session::Inbound => vec!['i', 'n'],
         Session::Outbound => vec!['o', 'u', 't'],
-        Session::Manual => vec!['m', 'a', 'n'],
+        //Session::Manual => vec!['m', 'a', 'n'],
         Session::Offline => vec!['o', 'f', 'f'],
     };
 
@@ -87,19 +93,19 @@ pub fn make_empty_id(node_id: &str, session: &Session, count: u64) -> Result<Str
             id.insert_str(0, "EMPTYOUT");
             id
         }
-        Session::Manual => {
-            let session_chars = vec!['m', 'a', 'n'];
-            for i in session_chars {
-                num += i as u64
-            }
-            for i in node_id.chars() {
-                num += i as u64
-            }
-            num += count;
-            let mut id = hex::encode(num.to_ne_bytes());
-            id.insert_str(0, "EMPTYMAN");
-            id
-        }
+        //Session::Manual => {
+        //    let session_chars = vec!['m', 'a', 'n'];
+        //    for i in session_chars {
+        //        num += i as u64
+        //    }
+        //    for i in node_id.chars() {
+        //        num += i as u64
+        //    }
+        //    num += count;
+        //    let mut id = hex::encode(num.to_ne_bytes());
+        //    id.insert_str(0, "EMPTYMAN");
+        //    id
+        //}
         Session::Offline => {
             let session_chars = vec!['o', 'f', 'f'];
             for i in session_chars {

+ 33 - 53
bin/dnetview/src/view.rs

@@ -16,8 +16,8 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use log::debug;
 use std::collections::HashMap;
-//use log::debug;
 
 use tui::{
     backend::Backend,
@@ -85,6 +85,9 @@ impl<'a> View {
         }
     }
 
+    // The order of the ordered_list created here must match the order
+    // of the Vec<ListItem> created in render_left().
+    // This is used to render_right() correctly.
     fn make_ordered_list(&mut self) {
         for obj in self.selectables.values() {
             match obj {
@@ -98,11 +101,9 @@ impl<'a> View {
                                 if !self.ordered_list.iter().any(|i| i == &inbound.dnet_id) {
                                     self.ordered_list.push(inbound.dnet_id.clone());
                                 }
-                                //for info in &inbound.info {
                                 if !self.ordered_list.iter().any(|i| i == &inbound.info.dnet_id) {
                                     self.ordered_list.push(inbound.info.dnet_id.clone());
                                 }
-                                //}
                             }
                         }
                         for outbound in &node.outbound {
@@ -110,11 +111,9 @@ impl<'a> View {
                                 if !self.ordered_list.iter().any(|i| i == &outbound.dnet_id) {
                                     self.ordered_list.push(outbound.dnet_id.clone());
                                 }
-                                //for info in &outbound.info {
                                 if !self.ordered_list.iter().any(|i| i == &outbound.info.dnet_id) {
                                     self.ordered_list.push(outbound.info.dnet_id.clone());
                                 }
-                                //}
                             }
                         }
                     }
@@ -132,12 +131,10 @@ impl<'a> View {
                 _ => (),
             }
         }
-        //debug!(target: "dnetview", "render_ids()::ordered_list: {:?}", self.ordered_list);
     }
 
-    // TODO: this function is dynamically resizing the msgs index
-    // according to what set of msgs is selected.
-    // it's ugly. would prefer something more simple
+    // TODO: this function displays msgs according to what id is
+    // selected.  It's ugly, would prefer something more simple.
     fn update_msg_index(&mut self) {
         if let Some(sel) = self.id_menu.state.selected() {
             if let Some(ord) = self.ordered_list.get(sel) {
@@ -165,31 +162,28 @@ impl<'a> View {
             .constraints(cnstrnts)
             .split(f.size());
 
-        self.render_ids(f, slice.clone())?;
+        self.render_left(f, slice.clone())?;
         if self.ordered_list.is_empty() {
             // we have not received any data
             Ok(())
         } else {
             // get the id at the current index
             match self.id_menu.state.selected() {
-                Some(i) => {
-                    //debug!(target: "dnetview", "render()::selected index: {}", i);
-                    match self.ordered_list.get(i) {
-                        Some(i) => {
-                            let id = i.clone();
-                            self.render_info(f, slice, id)?;
-                            Ok(())
-                        }
-                        None => Err(DnetViewError::NoIdAtIndex),
+                Some(i) => match self.ordered_list.get(i) {
+                    Some(i) => {
+                        let id = i.clone();
+                        self.render_right(f, slice, id)?;
+                        Ok(())
                     }
-                }
+                    None => Err(DnetViewError::NoIdAtIndex),
+                },
                 // nothing is selected right now
                 None => Ok(()),
             }
         }
     }
 
-    fn render_ids<B: Backend>(
+    fn render_left<B: Backend>(
         &mut self,
         f: &mut Frame<'_, B>,
         slice: Vec<Rect>,
@@ -215,13 +209,13 @@ impl<'a> View {
                         let names = ListItem::new(lines);
                         nodes.push(names);
 
-                        for inbound in &node.inbound {
-                            if !inbound.is_empty {
-                                let name = Span::styled(format!("    Inbound"), style);
-                                let lines = vec![Spans::from(name)];
-                                let names = ListItem::new(lines);
-                                nodes.push(names);
-                                //for info in &inbound.info {
+                        if !node.inbound.is_empty() {
+                            let name = Span::styled(format!("    Inbound"), style);
+                            let lines = vec![Spans::from(name)];
+                            let names = ListItem::new(lines);
+                            nodes.push(names);
+
+                            for inbound in &node.inbound {
                                 let mut infos = Vec::new();
                                 match inbound.info.addr.as_str() {
                                     "Null" => {
@@ -246,21 +240,19 @@ impl<'a> View {
                                         }
                                     }
                                 }
-
                                 let lines = vec![Spans::from(infos)];
                                 let names = ListItem::new(lines);
                                 nodes.push(names);
-                                //}
                             }
                         }
 
-                        for outbound in &node.outbound {
-                            if !outbound.is_empty {
-                                let name = Span::styled(format!("    Outbound"), style);
-                                let lines = vec![Spans::from(name)];
-                                let names = ListItem::new(lines);
-                                nodes.push(names);
-                                //for info in &outbound.info {
+                        if !&node.outbound.is_empty() {
+                            let name = Span::styled(format!("    Outbound"), style);
+                            let lines = vec![Spans::from(name)];
+                            let names = ListItem::new(lines);
+                            nodes.push(names);
+
+                            for outbound in &node.outbound {
                                 let mut infos = Vec::new();
                                 match outbound.info.addr.as_str() {
                                     "Null" => {
@@ -285,11 +277,9 @@ impl<'a> View {
                                         }
                                     }
                                 }
-
                                 let lines = vec![Spans::from(infos)];
                                 let names = ListItem::new(lines);
                                 nodes.push(names);
-                                //}
                             }
                         }
                     }
@@ -349,12 +339,13 @@ impl<'a> View {
         Ok(msg_list)
     }
 
-    fn render_info<B: Backend>(
+    fn render_right<B: Backend>(
         &mut self,
         f: &mut Frame<'_, B>,
         slice: Vec<Rect>,
         selected: String,
     ) -> DnetViewResult<()> {
+        debug!(target: "dnetview", "render_right() selected ID: {}", selected.clone());
         let style = Style::default();
         let mut lines = Vec::new();
 
@@ -363,11 +354,9 @@ impl<'a> View {
             return Ok(())
         } else {
             let info = self.selectables.get(&selected);
-            //debug!(target: "dnetview", "render_info()::selected {}", selected);
 
             match info {
                 Some(SelectableObject::Node(node)) => {
-                    //debug!(target: "dnetview", "render_info()::SelectableObject::Node");
                     lines.push(Spans::from(Span::styled("Type: Normal", style)));
                     lines.push(Spans::from(Span::styled("Hosts:", style)));
                     for host in &node.hosts {
@@ -375,7 +364,6 @@ impl<'a> View {
                     }
                 }
                 Some(SelectableObject::Session(session)) => {
-                    //debug!(target: "dnetview", "render_info()::SelectableObject::Session");
                     let addr = Span::styled(format!("Addr: {}", session.addr), style);
                     lines.push(Spans::from(addr));
 
@@ -387,16 +375,8 @@ impl<'a> View {
                         lines.push(Spans::from(addr));
                     }
                 }
-                Some(SelectableObject::Connect(connect)) => {
-                    // TODO: this renders in the top right and overwrites the msg log
-                    //let addr = Span::styled(format!("Addr: {}", connect.addr), style);
-                    //let random_id = Span::styled(format!("Random id: {}", connect.random_id), style);
-                    //let remote_id = Span::styled(format!("Remote id: {}", connect.remote_id), style);
-                    //lines.push(Spans::from(addr));
-                    //lines.push(Spans::from(random_id));
-                    //lines.push(Spans::from(remote_id));
-                    //debug!(target: "dnetview", "render_info()::SelectableObject::Connect");
-                    let text = self.parse_msg_list(connect.dnet_id.clone())?;
+                Some(SelectableObject::Slot(slot)) => {
+                    let text = self.parse_msg_list(slot.dnet_id.clone())?;
                     f.render_stateful_widget(text, slice[1], &mut self.msg_list.state);
                 }
                 Some(SelectableObject::Lilith(_lilith)) => {