mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
dnetview: improve NodeInfo data type + re-enable view
Pass inbound and outbound as two Vec<SessionInfo> into NodeInfo. Update and re-enable UI.
This commit is contained in:
@@ -63,7 +63,8 @@ pub struct NodeInfo {
|
||||
pub dnet_id: String,
|
||||
pub name: String,
|
||||
pub hosts: Vec<String>,
|
||||
pub info: Vec<SessionInfo>,
|
||||
pub inbound: Vec<SessionInfo>,
|
||||
pub outbound: Vec<SessionInfo>,
|
||||
pub is_offline: bool,
|
||||
}
|
||||
|
||||
@@ -72,10 +73,11 @@ impl NodeInfo {
|
||||
dnet_id: String,
|
||||
name: String,
|
||||
hosts: Vec<String>,
|
||||
info: Vec<SessionInfo>,
|
||||
inbound: Vec<SessionInfo>,
|
||||
outbound: Vec<SessionInfo>,
|
||||
is_offline: bool,
|
||||
) -> Self {
|
||||
Self { dnet_id, name, hosts, info, is_offline }
|
||||
Self { dnet_id, name, hosts, inbound, outbound, is_offline }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +111,7 @@ pub struct SlotInfo {
|
||||
pub dnet_id: String,
|
||||
pub node_id: String,
|
||||
pub addr: String,
|
||||
pub random_id: String,
|
||||
pub random_id: u64,
|
||||
pub remote_id: String,
|
||||
pub log: Vec<(NanoTimestamp, String, String)>,
|
||||
pub is_empty: bool,
|
||||
@@ -121,7 +123,7 @@ impl SlotInfo {
|
||||
dnet_id: String,
|
||||
node_id: String,
|
||||
addr: String,
|
||||
random_id: String,
|
||||
random_id: u64,
|
||||
remote_id: String,
|
||||
log: Vec<(NanoTimestamp, String, String)>,
|
||||
is_empty: bool,
|
||||
|
||||
@@ -33,7 +33,7 @@ use crate::{
|
||||
LilithInfo, Model, NetworkInfo, NodeInfo, SelectableObject, Session, SessionInfo, SlotInfo,
|
||||
},
|
||||
rpc::RpcConnect,
|
||||
util::{is_empty_session, make_connect_id, make_empty_id, make_node_id, make_session_id},
|
||||
util::{is_empty_session, make_empty_id, make_info_id, make_node_id, make_session_id},
|
||||
};
|
||||
|
||||
pub struct DataParser {
|
||||
@@ -118,19 +118,19 @@ impl DataParser {
|
||||
}
|
||||
|
||||
// If poll times out, inititalize data structures with empty values.
|
||||
async fn parse_offline(&self, name: String) -> DnetViewResult<()> {
|
||||
async fn parse_offline(&self, node_name: String) -> DnetViewResult<()> {
|
||||
let name = "Offline".to_string();
|
||||
let session_type = Session::Offline;
|
||||
|
||||
let mut slots: Vec<SlotInfo> = Vec::new();
|
||||
let mut info: Vec<SessionInfo> = Vec::new();
|
||||
let mut sessions: Vec<SessionInfo> = Vec::new();
|
||||
let hosts = Vec::new();
|
||||
|
||||
let node_id = make_node_id(&name)?;
|
||||
let node_id = make_node_id(&node_name)?;
|
||||
let dnet_id = make_empty_id(&node_id, &session_type, 0)?;
|
||||
let addr = "Null".to_string();
|
||||
let state = "Null".to_string();
|
||||
let random_id = "Null".to_string();
|
||||
let random_id = 0;
|
||||
let remote_id = "Null".to_string();
|
||||
let log = Vec::new();
|
||||
let is_empty = true;
|
||||
@@ -155,11 +155,19 @@ impl DataParser {
|
||||
slots,
|
||||
is_empty,
|
||||
);
|
||||
info.push(session_info);
|
||||
sessions.push(session_info);
|
||||
|
||||
let node = NodeInfo::new(node_id.clone(), name.clone(), hosts, info.clone(), is_empty);
|
||||
// TODO: clean this up
|
||||
let node = NodeInfo::new(
|
||||
node_id.clone(),
|
||||
name.clone(),
|
||||
hosts,
|
||||
sessions.clone(),
|
||||
sessions.clone(),
|
||||
is_empty,
|
||||
);
|
||||
|
||||
self.update_selectables(info, node).await?;
|
||||
self.update_selectables(node).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -178,14 +186,10 @@ impl DataParser {
|
||||
let inbound = self.parse_inbound(inbound, &dnet_id).await?;
|
||||
let outbound = self.parse_outbound(outbound, &dnet_id).await?;
|
||||
|
||||
let mut info: Vec<SessionInfo> = Vec::new();
|
||||
info.push(inbound.clone());
|
||||
info.push(outbound.clone());
|
||||
let node = NodeInfo::new(dnet_id, name, hosts, inbound.clone(), outbound.clone(), false);
|
||||
|
||||
let node = NodeInfo::new(dnet_id, name, hosts, info.clone(), false);
|
||||
|
||||
self.update_selectables(info.clone(), node).await?;
|
||||
self.update_msgs(info.clone()).await?;
|
||||
self.update_selectables(node).await?;
|
||||
self.update_msgs(inbound.clone(), outbound.clone()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -222,24 +226,24 @@ impl DataParser {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_msgs(&self, sessions: Vec<SessionInfo>) -> DnetViewResult<()> {
|
||||
for session in sessions {
|
||||
for connection in session.info {
|
||||
if !self.model.msg_map.lock().await.contains_key(&connection.dnet_id) {
|
||||
async fn update_msgs(
|
||||
&self,
|
||||
inbounds: Vec<SessionInfo>,
|
||||
outbounds: Vec<SessionInfo>,
|
||||
) -> DnetViewResult<()> {
|
||||
for inbound in inbounds {
|
||||
for info in inbound.info {
|
||||
if !self.model.msg_map.lock().await.contains_key(&info.dnet_id) {
|
||||
// we don't have this ID: it is a new node
|
||||
self.model
|
||||
.msg_map
|
||||
.lock()
|
||||
.await
|
||||
.insert(connection.dnet_id, connection.log.clone());
|
||||
self.model.msg_map.lock().await.insert(info.dnet_id, info.log.clone());
|
||||
} else {
|
||||
// we have this id: append the msg values
|
||||
match self.model.msg_map.lock().await.entry(connection.dnet_id) {
|
||||
match self.model.msg_map.lock().await.entry(info.dnet_id) {
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(connection.log);
|
||||
e.insert(info.log);
|
||||
}
|
||||
Entry::Occupied(mut e) => {
|
||||
for msg in connection.log {
|
||||
for msg in info.log {
|
||||
e.get_mut().push(msg);
|
||||
}
|
||||
}
|
||||
@@ -247,35 +251,70 @@ impl DataParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
for outbound in outbounds {
|
||||
for info in outbound.info {
|
||||
if !self.model.msg_map.lock().await.contains_key(&info.dnet_id) {
|
||||
// we don't have this ID: it is a new node
|
||||
self.model.msg_map.lock().await.insert(info.dnet_id, info.log.clone());
|
||||
} else {
|
||||
// we have this id: append the msg values
|
||||
match self.model.msg_map.lock().await.entry(info.dnet_id) {
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(info.log);
|
||||
}
|
||||
Entry::Occupied(mut e) => {
|
||||
for msg in info.log {
|
||||
e.get_mut().push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_selectables(
|
||||
&self,
|
||||
sessions: Vec<SessionInfo>,
|
||||
node: NodeInfo,
|
||||
) -> DnetViewResult<()> {
|
||||
async fn update_selectables(&self, node: NodeInfo) -> DnetViewResult<()> {
|
||||
if node.is_offline {
|
||||
let node_obj = SelectableObject::Node(node.clone());
|
||||
self.model.selectables.lock().await.insert(node.dnet_id.clone(), node_obj.clone());
|
||||
} else {
|
||||
let node_obj = SelectableObject::Node(node.clone());
|
||||
self.model.selectables.lock().await.insert(node.dnet_id.clone(), node_obj.clone());
|
||||
for session in sessions {
|
||||
if !session.is_empty {
|
||||
let session_obj = SelectableObject::Session(session.clone());
|
||||
for inbound in node.inbound {
|
||||
if !inbound.is_empty {
|
||||
let inbound_obj = SelectableObject::Session(inbound.clone());
|
||||
self.model
|
||||
.selectables
|
||||
.lock()
|
||||
.await
|
||||
.insert(session.clone().dnet_id, session_obj.clone());
|
||||
for connect in session.info {
|
||||
let connect_obj = SelectableObject::Connect(connect.clone());
|
||||
.insert(inbound.clone().dnet_id, inbound_obj.clone());
|
||||
for info in inbound.info {
|
||||
let info_obj = SelectableObject::Connect(info.clone());
|
||||
self.model
|
||||
.selectables
|
||||
.lock()
|
||||
.await
|
||||
.insert(connect.clone().dnet_id, connect_obj.clone());
|
||||
.insert(info.clone().dnet_id, info_obj.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
for outbound in node.outbound {
|
||||
if !outbound.is_empty {
|
||||
let outbound_obj = SelectableObject::Session(outbound.clone());
|
||||
self.model
|
||||
.selectables
|
||||
.lock()
|
||||
.await
|
||||
.insert(outbound.clone().dnet_id, outbound_obj.clone());
|
||||
for info in outbound.info {
|
||||
let info_obj = SelectableObject::Connect(info.clone());
|
||||
self.model
|
||||
.selectables
|
||||
.lock()
|
||||
.await
|
||||
.insert(info.clone().dnet_id, info_obj.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,35 +322,43 @@ impl DataParser {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn _parse_external_addr(&self, addr: &Option<&Value>) -> DnetViewResult<Option<String>> {
|
||||
match addr {
|
||||
Some(addr) => match addr.as_str() {
|
||||
Some(addr) => Ok(Some(addr.to_string())),
|
||||
None => Ok(None),
|
||||
},
|
||||
None => Err(DnetViewError::NoExternalAddr),
|
||||
}
|
||||
}
|
||||
//async fn _parse_external_addr(&self, addr: &Option<&Value>) -> DnetViewResult<Option<String>> {
|
||||
// match addr {
|
||||
// Some(addr) => match addr.as_str() {
|
||||
// Some(addr) => Ok(Some(addr.to_string())),
|
||||
// None => Ok(None),
|
||||
// },
|
||||
// None => Err(DnetViewError::NoExternalAddr),
|
||||
// }
|
||||
//}
|
||||
|
||||
async fn parse_inbound(&self, reply: &Value, node_id: &String) -> DnetViewResult<SessionInfo> {
|
||||
async fn parse_inbound(
|
||||
&self,
|
||||
reply: &Value,
|
||||
node_id: &String,
|
||||
) -> DnetViewResult<Vec<SessionInfo>> {
|
||||
let name = "Inbound".to_string();
|
||||
let session_type = Session::Inbound;
|
||||
let dnet_id = make_session_id(node_id, &session_type)?;
|
||||
let mut info: Vec<SlotInfo> = Vec::new();
|
||||
let session_id = make_session_id(node_id, &session_type)?;
|
||||
let mut slots: Vec<SlotInfo> = Vec::new();
|
||||
let mut sessions: Vec<SessionInfo> = Vec::new();
|
||||
|
||||
// TODO: improve this ugly hack.
|
||||
let slot_count = 0;
|
||||
let mut slot_count = 0;
|
||||
|
||||
// Dnetview is not enabled.
|
||||
// TODO: print warning on view
|
||||
if reply.is_null() {
|
||||
slot_count += 1;
|
||||
let dnet_id = make_empty_id(node_id, &session_type, slot_count)?;
|
||||
let node_id = node_id.to_string();
|
||||
let addr = "Null".to_string();
|
||||
let random_id = "Null".to_string();
|
||||
let random_id = 0;
|
||||
let remote_id = "Null".to_string();
|
||||
let log = Vec::new();
|
||||
let is_empty = true;
|
||||
|
||||
// info_id
|
||||
let slot = SlotInfo::new(
|
||||
dnet_id.clone(),
|
||||
node_id.clone(),
|
||||
@@ -321,47 +368,51 @@ impl DataParser {
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
slots.push(slot);
|
||||
// Check whether the session is empty.
|
||||
let is_empty = is_empty_session(&info);
|
||||
// TODO
|
||||
// let is_empty = is_empty_session(&slot);
|
||||
let is_empty = true;
|
||||
|
||||
let addr = "Null".to_string();
|
||||
let state = "Null".to_string();
|
||||
let session = SessionInfo::new(
|
||||
dnet_id.clone(),
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name,
|
||||
name.clone(),
|
||||
addr,
|
||||
state,
|
||||
info,
|
||||
slots.clone(),
|
||||
is_empty,
|
||||
);
|
||||
|
||||
return Ok(session)
|
||||
sessions.push(session);
|
||||
}
|
||||
|
||||
match reply.get("inbound") {
|
||||
Some(session) => {
|
||||
let inbound: Vec<serde_json::Map<String, Value>> =
|
||||
serde_json::from_value(session.clone()).unwrap();
|
||||
for slot in inbound {
|
||||
let addr = slot.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let slot_info: serde_json::Map<String, Value> =
|
||||
serde_json::from_value(slot.get("info").unwrap().clone()).unwrap();
|
||||
for session in inbound {
|
||||
let addr = session.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let info: serde_json::Map<String, Value> =
|
||||
serde_json::from_value(session.get("info").unwrap().clone()).unwrap();
|
||||
|
||||
let slot_addr = slot_info.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let random_id =
|
||||
slot_info.get("random_id").unwrap().as_str().unwrap().to_string();
|
||||
let remote_id =
|
||||
slot_info.get("remote_id").unwrap().as_str().unwrap().to_string();
|
||||
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(slot_info.get("log").unwrap().clone()).unwrap();
|
||||
serde_json::from_value(info.get("log").unwrap().clone()).unwrap();
|
||||
|
||||
// ...
|
||||
let node_id = node_id.to_string();
|
||||
let is_empty = false;
|
||||
// TODO: make this an option
|
||||
let state = String::new();
|
||||
|
||||
let slot = SlotInfo::new(
|
||||
dnet_id.clone(),
|
||||
info_id.clone(),
|
||||
node_id.clone(),
|
||||
slot_addr,
|
||||
random_id,
|
||||
@@ -369,80 +420,88 @@ impl DataParser {
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
}
|
||||
slots.push(slot);
|
||||
|
||||
// TODO: fixme
|
||||
let addr = String::new();
|
||||
// TODO: this should be an option
|
||||
let state = String::new();
|
||||
let node_id = node_id.to_string();
|
||||
let is_empty = false;
|
||||
let session =
|
||||
SessionInfo::new(dnet_id, node_id.clone(), name, addr, state, info, is_empty);
|
||||
Ok(session)
|
||||
let session = SessionInfo::new(
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name.clone(),
|
||||
addr,
|
||||
state,
|
||||
slots.clone(),
|
||||
is_empty,
|
||||
);
|
||||
sessions.push(session);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Empty data. Initialize empty values.
|
||||
// TODO: clean up empty info boilerplate.
|
||||
let dnet_id = make_empty_id(node_id, &session_type, slot_count)?;
|
||||
slot_count += 1;
|
||||
let info_id = make_empty_id(node_id, &session_type, slot_count)?;
|
||||
let node_id = node_id.to_string();
|
||||
let addr = "Null".to_string();
|
||||
let random_id = "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(
|
||||
dnet_id.clone(),
|
||||
info_id.clone(),
|
||||
node_id.clone(),
|
||||
addr,
|
||||
addr.clone(),
|
||||
random_id,
|
||||
remote_id,
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
slots.push(slot);
|
||||
// Check whether the session is empty.
|
||||
let is_empty = is_empty_session(&info);
|
||||
let is_empty = is_empty_session(&slots);
|
||||
|
||||
let addr = "Null".to_string();
|
||||
let state = "Null".to_string();
|
||||
let session = SessionInfo::new(
|
||||
dnet_id.clone(),
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name,
|
||||
addr,
|
||||
state,
|
||||
info,
|
||||
slots,
|
||||
is_empty,
|
||||
);
|
||||
return Ok(session)
|
||||
sessions.push(session);
|
||||
}
|
||||
}
|
||||
Ok(sessions)
|
||||
}
|
||||
|
||||
async fn parse_outbound(&self, reply: &Value, node_id: &String) -> DnetViewResult<SessionInfo> {
|
||||
async fn parse_outbound(
|
||||
&self,
|
||||
reply: &Value,
|
||||
node_id: &String,
|
||||
) -> DnetViewResult<Vec<SessionInfo>> {
|
||||
let name = "Outbound".to_string();
|
||||
let session_type = Session::Outbound;
|
||||
let dnet_id = make_session_id(node_id, &session_type)?;
|
||||
let mut info: Vec<SlotInfo> = Vec::new();
|
||||
let session_id = make_session_id(node_id, &session_type)?;
|
||||
let mut slots: Vec<SlotInfo> = Vec::new();
|
||||
let mut sessions: Vec<SessionInfo> = Vec::new();
|
||||
|
||||
// TODO: improve this ugly hack.
|
||||
let mut slot_count = 0;
|
||||
|
||||
// Dnetview is not enabled.
|
||||
if reply.is_null() {
|
||||
let dnet_id = make_empty_id(&node_id, &session_type, slot_count)?;
|
||||
slot_count += 1;
|
||||
let info_id = make_empty_id(&node_id, &session_type, slot_count)?;
|
||||
let node_id = node_id.to_string();
|
||||
let addr = "Null".to_string();
|
||||
let random_id = "Null".to_string();
|
||||
let random_id = 0;
|
||||
let remote_id = "Null".to_string();
|
||||
let log = Vec::new();
|
||||
let is_empty = false;
|
||||
|
||||
let slot = SlotInfo::new(
|
||||
dnet_id.clone(),
|
||||
info_id.clone(),
|
||||
node_id.clone(),
|
||||
addr,
|
||||
random_id,
|
||||
@@ -450,32 +509,48 @@ impl DataParser {
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
slots.push(slot);
|
||||
// Check whether the session is empty.
|
||||
let is_empty = is_empty_session(&slots);
|
||||
|
||||
let addr = "Null".to_string();
|
||||
let state = "Null".to_string();
|
||||
let session = SessionInfo::new(
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name.clone(),
|
||||
addr,
|
||||
state,
|
||||
slots.clone(),
|
||||
is_empty,
|
||||
);
|
||||
sessions.push(session);
|
||||
}
|
||||
|
||||
match reply.get("outbound") {
|
||||
Some(session) => {
|
||||
let inbound: Vec<serde_json::Map<String, Value>> =
|
||||
let outbound: Vec<serde_json::Map<String, Value>> =
|
||||
serde_json::from_value(session.clone()).unwrap();
|
||||
for slot in inbound {
|
||||
let addr = slot.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let state = slot.get("state").unwrap().as_str().unwrap().to_string();
|
||||
let slot_info: serde_json::Map<String, Value> =
|
||||
serde_json::from_value(slot.get("info").unwrap().clone()).unwrap();
|
||||
for session in outbound {
|
||||
let addr = session.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let state = session.get("state").unwrap().as_str().unwrap().to_string();
|
||||
let info: serde_json::Map<String, Value> =
|
||||
serde_json::from_value(session.get("info").unwrap().clone()).unwrap();
|
||||
|
||||
let slot_addr = slot_info.get("addr").unwrap().as_str().unwrap().to_string();
|
||||
let random_id =
|
||||
slot_info.get("random_id").unwrap().as_str().unwrap().to_string();
|
||||
let remote_id =
|
||||
slot_info.get("remote_id").unwrap().as_str().unwrap().to_string();
|
||||
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(slot_info.get("log").unwrap().clone()).unwrap();
|
||||
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(
|
||||
dnet_id.clone(),
|
||||
info_id.clone(),
|
||||
node_id.clone(),
|
||||
slot_addr,
|
||||
random_id,
|
||||
@@ -483,57 +558,59 @@ impl DataParser {
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
}
|
||||
slots.push(slot);
|
||||
|
||||
// TODO: fixme
|
||||
let addr = String::new();
|
||||
// TODO: this should be an option
|
||||
let state = String::new();
|
||||
let node_id = node_id.to_string();
|
||||
let is_empty = false;
|
||||
let session =
|
||||
SessionInfo::new(dnet_id, node_id.clone(), name, addr, state, info, is_empty);
|
||||
Ok(session)
|
||||
let session = SessionInfo::new(
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name.clone(),
|
||||
addr.clone(),
|
||||
state,
|
||||
slots.clone(),
|
||||
is_empty,
|
||||
);
|
||||
sessions.push(session);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Empty data. Initialize empty values.
|
||||
// TODO: clean up empty info boilerplate.
|
||||
let dnet_id = make_empty_id(node_id, &session_type, slot_count)?;
|
||||
slot_count += 1;
|
||||
let info_id = make_empty_id(node_id, &session_type, slot_count)?;
|
||||
let node_id = node_id.to_string();
|
||||
let addr = "Null".to_string();
|
||||
let random_id = "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(
|
||||
dnet_id.clone(),
|
||||
info_id.clone(),
|
||||
node_id.clone(),
|
||||
addr,
|
||||
addr.clone(),
|
||||
random_id,
|
||||
remote_id,
|
||||
log,
|
||||
is_empty,
|
||||
);
|
||||
info.push(slot);
|
||||
slots.push(slot);
|
||||
// Check whether the session is empty.
|
||||
let is_empty = is_empty_session(&info);
|
||||
let is_empty = is_empty_session(&slots);
|
||||
|
||||
let addr = "Null".to_string();
|
||||
let state = "Null".to_string();
|
||||
let session = SessionInfo::new(
|
||||
dnet_id.clone(),
|
||||
session_id.clone(),
|
||||
node_id.clone(),
|
||||
name,
|
||||
addr,
|
||||
addr.clone(),
|
||||
state,
|
||||
info,
|
||||
slots,
|
||||
is_empty,
|
||||
);
|
||||
return Ok(session)
|
||||
sessions.push(session);
|
||||
}
|
||||
}
|
||||
Ok(sessions)
|
||||
}
|
||||
|
||||
async fn parse_hosts(&self, hosts: &Value) -> DnetViewResult<Vec<String>> {
|
||||
|
||||
@@ -49,9 +49,9 @@ pub fn make_session_id(node_id: &str, session: &Session) -> Result<String> {
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn make_connect_id(id: &u64) -> Result<String> {
|
||||
pub fn make_info_id(id: &u64) -> Result<String> {
|
||||
let mut id = hex::encode(id.to_ne_bytes());
|
||||
id.insert_str(0, "CONNECT");
|
||||
id.insert_str(0, "INFO");
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ pub fn make_empty_id(node_id: &str, session: &Session, count: u64) -> Result<Str
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
// TODO: Rename to is empty slot.
|
||||
pub fn is_empty_session(connects: &[SlotInfo]) -> bool {
|
||||
return connects.iter().all(|conn| conn.is_empty)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
use std::collections::HashMap;
|
||||
//use log::debug;
|
||||
|
||||
use tui::{
|
||||
backend::Backend,
|
||||
@@ -92,14 +93,26 @@ impl<'a> View {
|
||||
self.ordered_list.push(node.dnet_id.clone());
|
||||
}
|
||||
if !node.is_offline {
|
||||
for session in &node.info {
|
||||
if !session.is_empty {
|
||||
if !self.ordered_list.iter().any(|i| i == &session.dnet_id) {
|
||||
self.ordered_list.push(session.dnet_id.clone());
|
||||
for inbound in &node.inbound {
|
||||
if !inbound.is_empty {
|
||||
if !self.ordered_list.iter().any(|i| i == &inbound.dnet_id) {
|
||||
self.ordered_list.push(inbound.dnet_id.clone());
|
||||
}
|
||||
for connection in &session.info {
|
||||
if !self.ordered_list.iter().any(|i| i == &connection.dnet_id) {
|
||||
self.ordered_list.push(connection.dnet_id.clone());
|
||||
for info in &inbound.info {
|
||||
if !self.ordered_list.iter().any(|i| i == &info.dnet_id) {
|
||||
self.ordered_list.push(info.dnet_id.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for outbound in &node.outbound {
|
||||
if !outbound.is_empty {
|
||||
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 == &info.dnet_id) {
|
||||
self.ordered_list.push(info.dnet_id.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,38 +214,71 @@ impl<'a> View {
|
||||
let lines = vec![Spans::from(name_span)];
|
||||
let names = ListItem::new(lines);
|
||||
nodes.push(names);
|
||||
for session in &node.info {
|
||||
if !session.is_empty {
|
||||
let name = Span::styled(format!(" {}", session.name), style);
|
||||
|
||||
for inbound in &node.inbound {
|
||||
if !inbound.is_empty {
|
||||
let name = Span::styled(format!(" {}", inbound.name), style);
|
||||
let lines = vec![Spans::from(name)];
|
||||
let names = ListItem::new(lines);
|
||||
nodes.push(names);
|
||||
for connection in &session.info {
|
||||
let mut info = Vec::new();
|
||||
match connection.addr.as_str() {
|
||||
for info in &inbound.info {
|
||||
let mut infos = Vec::new();
|
||||
match info.addr.as_str() {
|
||||
"Null" => {
|
||||
let style = Style::default()
|
||||
.fg(Color::Blue)
|
||||
.add_modifier(Modifier::ITALIC);
|
||||
let name = Span::styled(
|
||||
format!(" {} ", connection.addr),
|
||||
format!(" {} ", info.addr),
|
||||
style,
|
||||
);
|
||||
info.push(name);
|
||||
infos.push(name);
|
||||
}
|
||||
addr => {
|
||||
let name = Span::styled(
|
||||
format!(
|
||||
" {} ({})",
|
||||
addr, connection.remote_id
|
||||
),
|
||||
format!(" {} ({})", addr, info.remote_id),
|
||||
style,
|
||||
);
|
||||
info.push(name);
|
||||
infos.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
let lines = vec![Spans::from(info)];
|
||||
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.name), style);
|
||||
let lines = vec![Spans::from(name)];
|
||||
let names = ListItem::new(lines);
|
||||
nodes.push(names);
|
||||
for info in &outbound.info {
|
||||
let mut infos = Vec::new();
|
||||
match info.addr.as_str() {
|
||||
"Null" => {
|
||||
let style = Style::default()
|
||||
.fg(Color::Blue)
|
||||
.add_modifier(Modifier::ITALIC);
|
||||
let name = Span::styled(
|
||||
format!(" {} ", info.addr),
|
||||
style,
|
||||
);
|
||||
infos.push(name);
|
||||
}
|
||||
addr => {
|
||||
let name = Span::styled(
|
||||
format!(" {} ({})", addr, info.remote_id),
|
||||
style,
|
||||
);
|
||||
infos.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
let lines = vec![Spans::from(infos)];
|
||||
let names = ListItem::new(lines);
|
||||
nodes.push(names);
|
||||
}
|
||||
@@ -263,12 +309,12 @@ impl<'a> View {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_msg_list(&self, connect_id: String) -> DnetViewResult<List<'a>> {
|
||||
fn parse_msg_list(&self, info_id: String) -> DnetViewResult<List<'a>> {
|
||||
let send_style = Style::default().fg(Color::LightCyan);
|
||||
let recv_style = Style::default().fg(Color::DarkGray);
|
||||
let mut texts = Vec::new();
|
||||
let mut lines = Vec::new();
|
||||
let log = self.msg_list.msg_map.get(&connect_id);
|
||||
let log = self.msg_list.msg_map.get(&info_id);
|
||||
match log {
|
||||
Some(values) => {
|
||||
for (i, (t, k, v)) in values.iter().enumerate() {
|
||||
@@ -315,38 +361,19 @@ impl<'a> View {
|
||||
Some(SelectableObject::Node(node)) => {
|
||||
//debug!(target: "dnetview", "render_info()::SelectableObject::Node");
|
||||
lines.push(Spans::from(Span::styled("Type: Normal", style)));
|
||||
//match &node.external_addr {
|
||||
// Some(addr) => {
|
||||
// let node_info = Span::styled(format!("External addr: {}", addr), style);
|
||||
// lines.push(Spans::from(node_info));
|
||||
// }
|
||||
// None => {
|
||||
// let node_info = Span::styled("External addr: Null".to_string(), style);
|
||||
// lines.push(Spans::from(node_info));
|
||||
// }
|
||||
//}
|
||||
//lines.push(Spans::from(Span::styled(
|
||||
// format!("P2P state: {}", node.state),
|
||||
// style,
|
||||
//)));
|
||||
lines.push(Spans::from(Span::styled("Hosts:", style)));
|
||||
for host in &node.hosts {
|
||||
lines.push(Spans::from(Span::styled(format!(" {}", host), style)));
|
||||
}
|
||||
}
|
||||
Some(SelectableObject::Session(session)) => {
|
||||
//debug!(target: "dnetview", "render_info()::SelectableObject::Session");
|
||||
//if session.addr.is_some() {
|
||||
// let accept_addr = Span::styled(
|
||||
// format!("Accept addr: {}", session.addr.as_ref().unwrap()),
|
||||
// style,
|
||||
// );
|
||||
// lines.push(Spans::from(accept_addr));
|
||||
//}
|
||||
//if session.hosts.is_some() {
|
||||
// let hosts = Span::styled("Hosts:".to_string(), style);
|
||||
// lines.push(Spans::from(hosts));
|
||||
// for host in session.hosts.as_ref().unwrap() {
|
||||
// let host = Span::styled(format!(" {}", host), style);
|
||||
// lines.push(Spans::from(host));
|
||||
// }
|
||||
//}
|
||||
let addr = Span::styled(format!("Addr: {}", session.addr), style);
|
||||
lines.push(Spans::from(addr));
|
||||
|
||||
// TODO: this will be an option
|
||||
let addr = Span::styled(format!("State: {}", session.state), style);
|
||||
lines.push(Spans::from(addr));
|
||||
}
|
||||
Some(SelectableObject::Connect(connect)) => {
|
||||
//debug!(target: "dnetview", "render_info()::SelectableObject::Connect");
|
||||
|
||||
Reference in New Issue
Block a user