فهرست منبع

dnetview: cleanup

* pass references instead of consuming values wherever possible
* create more descriptive function names
* seperate distinct behavior into separate functions
* tidy variable names and standarize across program
lunar-mining 4 سال پیش
والد
کامیت
acd6d9549d
4فایلهای تغییر یافته به همراه209 افزوده شده و 200 حذف شده
  1. 122 114
      bin/dnetview/src/main.rs
  2. 23 24
      bin/dnetview/src/model.rs
  3. 5 13
      bin/dnetview/src/util.rs
  4. 59 49
      bin/dnetview/src/view.rs

+ 122 - 114
bin/dnetview/src/main.rs

@@ -33,13 +33,13 @@ use dnetview::{
     view::{IdListView, NodeInfoView, View},
 };
 
-struct DNetView {
+struct DnetView {
     url: Url,
     name: String,
 }
 
-impl DNetView {
-    pub fn new(url: Url, name: String) -> Self {
+impl DnetView {
+    fn new(url: Url, name: String) -> Self {
         Self { url, name }
     }
 
@@ -122,9 +122,8 @@ async fn main() -> Result<()> {
         .each(0..nthreads, |_| smol::future::block_on(ex.run(shutdown.recv())))
         .finish(|| {
             smol::future::block_on(async move {
-                run_rpc(&config, ex2.clone(), model.clone()).await?;
-                // msg_log
-                render(&mut terminal, model.clone()).await?;
+                poll_and_update_model(&config, ex2.clone(), model.clone()).await?;
+                render_view(&mut terminal, model.clone()).await?;
                 drop(signal);
                 Ok::<(), darkfi::Error>(())
             })
@@ -133,15 +132,21 @@ async fn main() -> Result<()> {
     result
 }
 
-async fn run_rpc(config: &DnvConfig, ex: Arc<Executor<'_>>, model: Arc<Model>) -> Result<()> {
-    for node in config.nodes.clone() {
-        let client = DNetView::new(Url::parse(&node.rpc_url)?, node.name);
+// create a new RPC instance for every node in the config file
+// spawn poll() and detach in the background
+async fn poll_and_update_model(
+    config: &DnvConfig,
+    ex: Arc<Executor<'_>>,
+    model: Arc<Model>,
+) -> Result<()> {
+    for node in &config.nodes {
+        let client = DnetView::new(Url::parse(&node.rpc_url)?, node.name.clone());
         ex.spawn(poll(client, model.clone())).detach();
     }
     Ok(())
 }
 
-async fn poll(client: DNetView, model: Arc<Model>) -> Result<()> {
+async fn poll(client: DnetView, model: Arc<Model>) -> Result<()> {
     loop {
         let reply = client.get_info().await?;
 
@@ -157,7 +162,7 @@ async fn poll(client: DNetView, model: Arc<Model>) -> Result<()> {
 
 async fn parse_data(
     reply: &serde_json::Map<String, Value>,
-    client: &DNetView,
+    client: &DnetView,
     model: Arc<Model>,
 ) -> Result<()> {
     let _ext_addr = reply.get("external_addr");
@@ -170,18 +175,18 @@ async fn parse_data(
     let node_name = &client.name;
     let node_id = make_node_id(node_name)?;
 
-    let in_session = parse_inbound(inbound, node_id.clone()).await?;
-    let out_session = parse_outbound(outbound, node_id.clone()).await?;
-    let man_session = parse_manual(manual, node_id.clone()).await?;
+    let in_session = parse_inbound(inbound, &node_id).await?;
+    let out_session = parse_outbound(outbound, &node_id).await?;
+    let man_session = parse_manual(manual, &node_id).await?;
 
     sessions.push(in_session.clone());
     sessions.push(out_session.clone());
     sessions.push(man_session.clone());
 
-    let nodes = NodeInfo::new(node_id.clone(), node_name.to_string(), sessions.clone());
+    let node = NodeInfo::new(node_id.clone(), node_name.to_string(), sessions.clone());
 
-    update_nodes(model.clone(), nodes.clone(), node_id.clone()).await;
-    update_selectable_and_ids(model.clone(), sessions.clone(), nodes.clone()).await?;
+    update_node(model.clone(), node.clone(), node_id.clone()).await;
+    update_selectable_and_ids(model.clone(), sessions.clone(), node.clone()).await?;
     update_msgs(model.clone(), sessions.clone()).await?;
 
     //debug!("IDS: {:?}", model.ids.lock().await);
@@ -193,10 +198,10 @@ async fn parse_data(
 async fn update_msgs(model: Arc<Model>, sessions: Vec<SessionInfo>) -> Result<()> {
     for session in sessions {
         for connection in session.children {
-            if !model.msg_log.lock().await.contains_key(&connection.connect_id) {
-                model.msg_log.lock().await.insert(connection.connect_id, connection.msg_log);
+            if !model.msg_log.lock().await.contains_key(&connection.id) {
+                model.msg_log.lock().await.insert(connection.id, connection.msg_log);
             } else {
-                match model.msg_log.lock().await.entry(connection.connect_id) {
+                match model.msg_log.lock().await.entry(connection.id) {
                     Entry::Vacant(e) => {
                         e.insert(connection.msg_log);
                     }
@@ -217,35 +222,36 @@ async fn update_ids(model: Arc<Model>, id: String) {
     model.ids.lock().await.insert(id);
 }
 
-async fn update_nodes(model: Arc<Model>, node: NodeInfo, id: String) {
+async fn update_node(model: Arc<Model>, node: NodeInfo, id: String) {
     model.nodes.lock().await.insert(id, node);
 }
 
 async fn update_selectable_and_ids(
     model: Arc<Model>,
     sessions: Vec<SessionInfo>,
-    nodes: NodeInfo,
+    node: NodeInfo,
 ) -> Result<()> {
-    let node_obj = SelectableObject::Node(nodes.clone());
-    model.selectables.lock().await.insert(nodes.node_id.clone(), node_obj);
-    update_ids(model.clone(), nodes.node_id.clone()).await;
+    let node_obj = SelectableObject::Node(node.clone());
+    model.selectables.lock().await.insert(node.id.clone(), node_obj);
+    update_ids(model.clone(), node.id.clone()).await;
     for session in sessions.clone() {
         let session_obj = SelectableObject::Session(session.clone());
-        model.selectables.lock().await.insert(session.clone().session_id, session_obj);
-        update_ids(model.clone(), session.clone().session_id).await;
+        model.selectables.lock().await.insert(session.clone().id, session_obj);
+        update_ids(model.clone(), session.clone().id).await;
         for connect in session.children {
             let connect_obj = SelectableObject::Connect(connect.clone());
-            model.selectables.lock().await.insert(connect.clone().connect_id, connect_obj);
-            update_ids(model.clone(), connect.clone().connect_id).await;
+            model.selectables.lock().await.insert(connect.clone().id, connect_obj);
+            update_ids(model.clone(), connect.clone().id).await;
         }
     }
     Ok(())
 }
 
-async fn parse_inbound(inbound: &Value, node_id: String) -> Result<SessionInfo> {
-    let session_name = "Inbound".to_string();
+async fn parse_inbound(inbound: &Value, node_id: &String) -> Result<SessionInfo> {
+    let name = "Inbound".to_string();
     let session_type = Session::Inbound;
-    let session_id = make_session_id(node_id.clone(), &session_type)?;
+    let parent = node_id.to_string();
+    let id = make_session_id(&parent, &session_type)?;
     let mut connects: Vec<ConnectInfo> = Vec::new();
     let connections = &inbound["connected"];
     let mut connect_count = 0;
@@ -256,17 +262,23 @@ async fn parse_inbound(inbound: &Value, node_id: String) -> Result<SessionInfo>
                 true => {
                     connect_count += 1;
                     // channel is empty. initialize with empty values
-                    // TODO: fix this
-                    let connect_id = make_empty_id(node_id.clone(), &session_type, connect_count)?;
+                    let id = make_empty_id(&node_id, &session_type, connect_count)?;
                     let addr = "Null".to_string();
-                    let msg = "Null".to_string();
-                    let status = "Null".to_string();
-                    let is_empty = true;
-                    let parent = session_id.clone();
                     let state = "Null".to_string();
+                    let parent = parent.clone();
                     let msg_log = Vec::new();
+                    let is_empty = true;
+                    let last_msg = "Null".to_string();
+                    let last_status = "Null".to_string();
                     let connect_info = ConnectInfo::new(
-                        connect_id, addr, is_empty, msg, status, state, msg_log, parent,
+                        id,
+                        addr,
+                        state,
+                        parent,
+                        msg_log,
+                        is_empty,
+                        last_msg,
+                        last_status,
                     );
                     connects.push(connect_info.clone());
                 }
@@ -275,41 +287,38 @@ async fn parse_inbound(inbound: &Value, node_id: String) -> Result<SessionInfo>
                     for k in connect.keys() {
                         let node = connect.get(k);
                         let addr = k.to_string();
-                        let msg =
-                            node.unwrap().get("last_msg").unwrap().as_str().unwrap().to_string();
-                        let status =
-                            node.unwrap().get("last_status").unwrap().as_str().unwrap().to_string();
-                        // TODO: state
                         let id = node.unwrap().get("random_id").unwrap().as_u64().unwrap();
-                        let connect_id = make_connect_id(id)?;
+                        let id = make_connect_id(&id)?;
                         let state = "state".to_string();
-                        let is_empty = false;
-                        let parent = session_id.clone();
+                        let parent = parent.clone();
                         let msg_values = node.unwrap().get("log").unwrap().as_array().unwrap();
-                        // append to existing values
-                        //let mut writer = msg_log.write().unwrap();
-                        //writer.insert(connect_id, connect.clone());
-                        let mut msgs: Vec<(String, String)> = Vec::new();
+                        let mut msg_log: Vec<(String, String)> = Vec::new();
                         for msg in msg_values {
                             let msg: (String, String) = serde_json::from_value(msg.clone())?;
-                            msgs.push(msg);
+                            msg_log.push(msg);
                         }
+                        let is_empty = false;
+                        let last_msg =
+                            node.unwrap().get("last_msg").unwrap().as_str().unwrap().to_string();
+                        let last_status =
+                            node.unwrap().get("last_status").unwrap().as_str().unwrap().to_string();
                         let connect_info = ConnectInfo::new(
-                            connect_id, addr, is_empty, msg, status, state, msgs, parent,
+                            id,
+                            addr,
+                            state,
+                            parent,
+                            msg_log,
+                            is_empty,
+                            last_msg,
+                            last_status,
                         );
                         connects.push(connect_info.clone());
                     }
                 }
             }
-            let is_empty = is_empty_session(connects.clone());
-
-            let session_info = SessionInfo::new(
-                session_name,
-                session_id.clone(),
-                node_id.clone(),
-                connects.clone(),
-                is_empty,
-            );
+            let is_empty = is_empty_session(&connects);
+
+            let session_info = SessionInfo::new(id, name, is_empty, parent, connects);
             Ok(session_info)
         }
         None => Err(Error::ValueIsNotObject),
@@ -317,38 +326,38 @@ async fn parse_inbound(inbound: &Value, node_id: String) -> Result<SessionInfo>
 }
 
 // TODO: placeholder for now
-async fn parse_manual(_manual: &Value, node_id: String) -> Result<SessionInfo> {
-    let session_name = "Manual".to_string();
+async fn parse_manual(_manual: &Value, node_id: &String) -> Result<SessionInfo> {
+    let name = "Manual".to_string();
     let session_type = Session::Manual;
     let mut connects: Vec<ConnectInfo> = Vec::new();
+    let parent = node_id.to_string();
 
-    let session_id = make_session_id(node_id.clone(), &session_type)?;
+    let session_id = make_session_id(&parent, &session_type)?;
     let id: u64 = 0;
-    let connect_id = make_connect_id(id)?;
+    let connect_id = make_connect_id(&id)?;
     let addr = "Null".to_string();
-    let msg = "Null".to_string();
-    let status = "Null".to_string();
-    let is_empty = true;
-    let parent = session_id.clone();
     let state = "Null".to_string();
     let msg_log = Vec::new();
+    let is_empty = true;
+    let msg = "Null".to_string();
+    let status = "Null".to_string();
     let connect_info =
-        ConnectInfo::new(connect_id, addr, is_empty, msg, status, state, msg_log, parent);
+        ConnectInfo::new(connect_id.clone(), addr, state, parent, msg_log, is_empty, msg, status);
     connects.push(connect_info.clone());
-    let is_empty = is_empty_session(connects.clone());
-    //let is_empty = false;
-    let session_info =
-        SessionInfo::new(session_name, session_id, node_id, connects.clone(), is_empty);
+    let parent = connect_id.clone();
+    let is_empty = is_empty_session(&connects);
+    let session_info = SessionInfo::new(session_id, name, is_empty, parent, connects.clone());
 
     Ok(session_info)
 }
 
-async fn parse_outbound(outbound: &Value, node_id: String) -> Result<SessionInfo> {
-    let session_name = "Outbound".to_string();
+async fn parse_outbound(outbound: &Value, node_id: &String) -> Result<SessionInfo> {
+    let name = "Outbound".to_string();
     let session_type = Session::Outbound;
+    let parent = node_id.to_string();
+    let id = make_session_id(&parent, &session_type)?;
     let mut connects: Vec<ConnectInfo> = Vec::new();
     let slots = &outbound["slots"];
-    let session_id = make_session_id(node_id.clone(), &session_type)?;
     let mut slot_count = 0;
 
     match slots.as_array() {
@@ -358,89 +367,88 @@ async fn parse_outbound(outbound: &Value, node_id: String) -> Result<SessionInfo
                 match slot["channel"].is_null() {
                     true => {
                         // channel is empty. initialize with empty values
-                        // TODO: fix this
-                        let connect_id = make_empty_id(node_id.clone(), &session_type, slot_count)?;
-                        let is_empty = true;
+                        let id = make_empty_id(&node_id, &session_type, slot_count)?;
                         let addr = "Null".to_string();
                         let state = &slot["state"];
-                        let msg = "Null".to_string();
-                        let status = "Null".to_string();
-                        // TODO: msg log
+                        let state = state.as_str().unwrap().to_string();
+                        let parent = parent.clone();
                         let msg_log = Vec::new();
-                        let parent = session_id.clone();
+                        let is_empty = true;
+                        let last_msg = "Null".to_string();
+                        let last_status = "Null".to_string();
                         let connect_info = ConnectInfo::new(
-                            connect_id,
+                            id,
                             addr,
-                            is_empty,
-                            msg,
-                            status,
-                            state.as_str().unwrap().to_string(),
-                            msg_log,
+                            state,
                             parent,
+                            msg_log,
+                            is_empty,
+                            last_msg,
+                            last_status,
                         );
                         connects.push(connect_info.clone());
                     }
                     false => {
                         // channel is not empty. initialize with whole values
                         let channel = &slot["channel"];
-                        let last_msg = channel["last_msg"].as_str().unwrap().to_string();
-                        let last_status = channel["last_status"].as_str().unwrap().to_string();
                         let id = channel["random_id"].as_u64().unwrap();
-                        let msg_values = channel["log"].as_array().unwrap();
-                        let connect_id = make_connect_id(id)?;
-                        let is_empty = false;
+                        let id = make_connect_id(&id)?;
                         let addr = &slot["addr"];
+                        let addr = addr.as_str().unwrap().to_string();
                         let state = &slot["state"];
-                        let parent = session_id.clone();
-                        // append to existing values
-                        let mut msgs: Vec<(String, String)> = Vec::new();
+                        let state = state.as_str().unwrap().to_string();
+                        let parent = parent.clone();
+                        let msg_values = channel["log"].as_array().unwrap();
+                        let mut msg_log: Vec<(String, String)> = Vec::new();
                         for msg in msg_values {
                             let msg: (String, String) = serde_json::from_value(msg.clone())?;
-                            msgs.push(msg);
+                            msg_log.push(msg);
                         }
+                        let is_empty = false;
+                        let last_msg = channel["last_msg"].as_str().unwrap().to_string();
+                        let last_status = channel["last_status"].as_str().unwrap().to_string();
                         let connect_info = ConnectInfo::new(
-                            connect_id,
-                            addr.as_str().unwrap().to_string(),
+                            id,
+                            addr,
+                            state,
+                            parent,
+                            msg_log,
                             is_empty,
                             last_msg,
                             last_status,
-                            state.as_str().unwrap().to_string(),
-                            msgs,
-                            parent,
                         );
                         connects.push(connect_info.clone());
                     }
                 }
             }
 
-            let is_empty = is_empty_session(connects.clone());
+            let is_empty = is_empty_session(&connects);
 
-            let session_info =
-                SessionInfo::new(session_name, session_id, node_id, connects.clone(), is_empty);
+            let session_info = SessionInfo::new(id, name, is_empty, parent, connects);
             Ok(session_info)
         }
         None => Err(Error::ValueIsNotObject),
     }
 }
 
-async fn render<B: Backend>(terminal: &mut Terminal<B>, model: Arc<Model>) -> Result<()> {
+async fn render_view<B: Backend>(terminal: &mut Terminal<B>, model: Arc<Model>) -> Result<()> {
     let mut asi = async_stdin();
 
     terminal.clear()?;
 
-    let active_ids = IdListView::new(FxHashSet::default());
-    let info_list = NodeInfoView::new(FxHashMap::default());
-    let selectable = FxHashMap::default();
+    let nodes = NodeInfoView::new(FxHashMap::default());
     let msg_log = FxHashMap::default();
+    let active_ids = IdListView::new(FxHashSet::default());
+    let selectables = FxHashMap::default();
 
-    let mut view = View::new(active_ids.clone(), info_list.clone(), selectable, msg_log);
+    let mut view = View::new(nodes, msg_log, active_ids, selectables);
     view.active_ids.state.select(Some(0));
 
     loop {
         view.update(
             model.nodes.lock().await.clone(),
-            model.selectables.lock().await.clone(),
             model.msg_log.lock().await.clone(),
+            model.selectables.lock().await.clone(),
         );
 
         terminal.draw(|f| {

+ 23 - 24
bin/dnetview/src/model.rs

@@ -20,79 +20,78 @@ pub enum SelectableObject {
 pub struct Model {
     pub ids: Mutex<FxHashSet<String>>,
     pub nodes: Mutex<FxHashMap<String, NodeInfo>>,
-    pub selectables: Mutex<FxHashMap<String, SelectableObject>>,
     pub msg_log: Mutex<FxHashMap<String, Vec<(String, String)>>>,
+    pub selectables: Mutex<FxHashMap<String, SelectableObject>>,
 }
 
 impl Model {
     pub fn new(
         ids: Mutex<FxHashSet<String>>,
         nodes: Mutex<FxHashMap<String, NodeInfo>>,
-        selectables: Mutex<FxHashMap<String, SelectableObject>>,
         msg_log: Mutex<FxHashMap<String, Vec<(String, String)>>>,
+        selectables: Mutex<FxHashMap<String, SelectableObject>>,
     ) -> Model {
-        Model { ids, nodes, selectables, msg_log }
+        Model { ids, nodes, msg_log, selectables }
     }
 }
 
-// TODO: tidy variable names to avoid redudancies like NodeInfo.node_id
 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
 pub struct NodeInfo {
-    pub node_id: String,
-    pub node_name: String,
+    pub id: String,
+    pub name: String,
     pub children: Vec<SessionInfo>,
 }
 
 impl NodeInfo {
-    pub fn new(node_id: String, node_name: String, children: Vec<SessionInfo>) -> NodeInfo {
-        NodeInfo { node_id, node_name, children }
+    pub fn new(id: String, name: String, children: Vec<SessionInfo>) -> NodeInfo {
+        NodeInfo { id, name, children }
     }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
 pub struct SessionInfo {
-    pub session_name: String,
-    pub session_id: String,
+    pub id: String,
+    pub name: String,
     pub parent: String,
-    pub children: Vec<ConnectInfo>,
     pub is_empty: bool,
+    pub children: Vec<ConnectInfo>,
 }
 
 impl SessionInfo {
     pub fn new(
-        session_name: String,
-        session_id: String,
+        id: String,
+        name: String,
+        is_empty: bool,
         parent: String,
         children: Vec<ConnectInfo>,
-        is_empty: bool,
     ) -> SessionInfo {
-        SessionInfo { session_name, session_id, parent, children, is_empty }
+        SessionInfo { id, name, is_empty, parent, children }
     }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
 pub struct ConnectInfo {
-    pub connect_id: String,
+    pub id: String,
     pub addr: String,
+    pub state: String,
+    pub parent: String,
+    pub msg_log: Vec<(String, String)>,
     pub is_empty: bool,
     pub last_msg: String,
     pub last_status: String,
-    pub state: String,
-    pub msg_log: Vec<(String, String)>,
-    pub parent: String,
 }
 
 impl ConnectInfo {
     pub fn new(
-        connect_id: String,
+        id: String,
         addr: String,
+        state: String,
+        parent: String,
+        msg_log: Vec<(String, String)>,
         is_empty: bool,
         last_msg: String,
         last_status: String,
-        state: String,
-        msg_log: Vec<(String, String)>,
-        parent: String,
     ) -> ConnectInfo {
-        ConnectInfo { connect_id, addr, is_empty, last_msg, last_status, state, msg_log, parent }
+        ConnectInfo { id, addr, state, parent, msg_log, is_empty, last_msg, last_status }
     }
 }

+ 5 - 13
bin/dnetview/src/util.rs

@@ -1,12 +1,11 @@
 use crate::model::{ConnectInfo, Session};
 use darkfi::{util::serial, Result};
-use rand::{thread_rng, Rng};
 
 pub fn make_node_id(node_name: &String) -> Result<String> {
     Ok(serial::serialize_hex(node_name))
 }
 
-pub fn make_session_id(node_id: String, session: &Session) -> Result<String> {
+pub fn make_session_id(node_id: &String, session: &Session) -> Result<String> {
     let mut num = 0_u64;
 
     match session {
@@ -34,18 +33,11 @@ pub fn make_session_id(node_id: String, session: &Session) -> Result<String> {
     Ok(serial::serialize_hex(&num))
 }
 
-pub fn make_connect_id(id: u64) -> Result<String> {
-    Ok(serial::serialize_hex(&id))
+pub fn make_connect_id(id: &u64) -> Result<String> {
+    Ok(serial::serialize_hex(id))
 }
 
-// we use a random id for empty connections
-pub fn generate_id() -> Result<String> {
-    let mut rng = thread_rng();
-    let id: u32 = rng.gen();
-    Ok(serial::serialize_hex(&id))
-}
-
-pub fn make_empty_id(node_id: String, session: &Session, count: u64) -> Result<String> {
+pub fn make_empty_id(node_id: &String, session: &Session, count: u64) -> Result<String> {
     let mut num = 0_u64;
 
     match session {
@@ -75,6 +67,6 @@ pub fn make_empty_id(node_id: String, session: &Session, count: u64) -> Result<S
     Ok(serial::serialize_hex(&num))
 }
 
-pub fn is_empty_session(connects: Vec<ConnectInfo>) -> bool {
+pub fn is_empty_session(connects: &Vec<ConnectInfo>) -> bool {
     return connects.iter().all(|conn| conn.is_empty)
 }

+ 59 - 49
bin/dnetview/src/view.rs

@@ -1,4 +1,4 @@
-use darkfi::error::{Error, Result};
+//use darkfi::error::{Error, Result};
 use fxhash::{FxHashMap, FxHashSet};
 use tui::widgets::ListState;
 
@@ -16,27 +16,27 @@ use crate::model::{NodeInfo, SelectableObject};
 
 #[derive(Debug)]
 pub struct View {
-    pub active_ids: IdListView,
     pub nodes: NodeInfoView,
-    pub selectables: FxHashMap<String, SelectableObject>,
     pub msg_log: FxHashMap<String, Vec<(String, String)>>,
+    pub active_ids: IdListView,
+    pub selectables: FxHashMap<String, SelectableObject>,
 }
 
 impl View {
     pub fn new(
-        active_ids: IdListView,
         nodes: NodeInfoView,
-        selectables: FxHashMap<String, SelectableObject>,
         msg_log: FxHashMap<String, Vec<(String, String)>>,
+        active_ids: IdListView,
+        selectables: FxHashMap<String, SelectableObject>,
     ) -> View {
-        View { active_ids, nodes, selectables, msg_log }
+        View { nodes, msg_log, active_ids, selectables }
     }
 
     pub fn update(
         &mut self,
         nodes: FxHashMap<String, NodeInfo>,
-        selectables: FxHashMap<String, SelectableObject>,
         msg_log: FxHashMap<String, Vec<(String, String)>>,
+        selectables: FxHashMap<String, SelectableObject>,
     ) {
         self.update_nodes(nodes);
         self.update_selectable(selectables);
@@ -58,12 +58,12 @@ impl View {
 
     fn update_active_ids(&mut self) {
         for info in self.nodes.infos.values() {
-            self.active_ids.ids.insert(info.node_id.to_string());
+            self.active_ids.ids.insert(info.id.to_string());
             for child in &info.children {
                 if !child.is_empty == true {
-                    self.active_ids.ids.insert(child.session_id.to_string());
+                    self.active_ids.ids.insert(child.id.to_string());
                     for child in &child.children {
-                        self.active_ids.ids.insert(child.connect_id.to_string());
+                        self.active_ids.ids.insert(child.id.to_string());
                     }
                 }
             }
@@ -77,26 +77,61 @@ impl View {
     }
 
     pub fn render<B: Backend>(&mut self, f: &mut Frame<'_, B>) {
-        let mut nodes = Vec::new();
-        let mut ids = Vec::new();
+        let margin = 2;
+        let direction = Direction::Horizontal;
+        let cnstrnts = vec![Constraint::Percentage(50), Constraint::Percentage(50)];
+
+        let slice = Layout::default()
+            .direction(direction)
+            .margin(margin)
+            .constraints(cnstrnts)
+            .split(f.size());
+
+        let mut id_list = self.render_id_list(f, slice.clone());
+
+        // remove any duplicates
+        id_list.dedup();
+
+        // get the id at the current index
+        match self.active_ids.state.selected() {
+            Some(i) => {
+                match id_list.get(i) {
+                    Some(i) => {
+                        self.render_info(f, slice.clone(), i.to_string());
+                    }
+                    None => {
+                        // TODO: Error
+                    }
+                }
+            }
+            None => {
+                // TODO: nothing is selected
+            }
+        }
+    }
+
+    fn render_id_list<B: Backend>(
+        &mut self,
+        f: &mut Frame<'_, B>,
+        slice: Vec<Rect>,
+    ) -> Vec<String> {
         let style = Style::default();
-        let list_margin = 2;
-        let list_direction = Direction::Horizontal;
-        let list_cnstrnts = vec![Constraint::Percentage(50), Constraint::Percentage(50)];
+        let mut nodes = Vec::new();
+        let mut ids: Vec<String> = Vec::new();
 
         for info in self.nodes.infos.values() {
-            let name_span = Span::raw(&info.node_name);
+            let name_span = Span::raw(&info.name);
             let lines = vec![Spans::from(name_span)];
             let names = ListItem::new(lines);
             nodes.push(names);
-            ids.push(&info.node_id);
+            ids.push(info.id.clone());
             for session in &info.children {
                 if !session.is_empty == true {
-                    let name = Span::styled(format!("    {}", session.session_name), style);
+                    let name = Span::styled(format!("    {}", session.name), style);
                     let lines = vec![Spans::from(name)];
                     let names = ListItem::new(lines);
                     nodes.push(names);
-                    ids.push(&session.session_id);
+                    ids.push(session.id.clone());
                     for connection in &session.children {
                         let mut info = Vec::new();
                         let name = Span::styled(format!("        {}", connection.addr), style);
@@ -124,41 +159,18 @@ impl View {
                         let lines = vec![Spans::from(info)];
                         let names = ListItem::new(lines);
                         nodes.push(names);
-                        ids.push(&connection.connect_id);
+                        ids.push(connection.id.clone());
                     }
                 }
             }
         }
 
-        let slice = Layout::default()
-            .direction(list_direction)
-            .margin(list_margin)
-            .constraints(list_cnstrnts)
-            .split(f.size());
-
         let nodes =
             List::new(nodes).block(Block::default().borders(Borders::ALL)).highlight_symbol(">> ");
 
         f.render_stateful_widget(nodes, slice[0], &mut self.active_ids.state);
 
-        ids.dedup();
-        // get the id at the current index
-        match self.active_ids.state.selected() {
-            Some(i) => {
-                match ids.get(i) {
-                    Some(i) => {
-                        self.render_info(f, slice.clone(), i.to_string());
-                        // found id
-                    }
-                    None => {
-                        // TODO: Error
-                    }
-                }
-            }
-            None => {
-                // TODO: nothing is selected
-            }
-        }
+        return ids
     }
 
     fn render_info<B: Backend>(
@@ -168,23 +180,21 @@ impl View {
         selected: String,
     ) {
         let style = Style::default();
-        //let mut infos = Vec::new();
         let mut spans = Vec::new();
-        //let mut msgs = Vec::new();
 
         let info = self.selectables.get(&selected);
 
         match info {
-            Some(SelectableObject::Node(node)) => {
+            Some(SelectableObject::Node(_node)) => {
                 let name_span = Spans::from("Node Info");
                 spans.push(name_span);
             }
-            Some(SelectableObject::Session(session)) => {
+            Some(SelectableObject::Session(_session)) => {
                 let name_span = Spans::from("Session Info");
                 spans.push(name_span);
             }
             Some(SelectableObject::Connect(connect)) => {
-                let log = self.msg_log.get(&connect.connect_id);
+                let log = self.msg_log.get(&connect.id);
                 match log {
                     Some(values) => {
                         for (k, v) in values {