|
@@ -1,4 +1,115 @@
|
|
|
# dnetview
|
|
# dnetview
|
|
|
|
|
|
|
|
-a simple tui to explore darkfi ircd network topology.
|
|
|
|
|
-lists all active nodes, their connections and recent messages.
|
|
|
|
|
|
|
+A simple tui to explore darkfi ircd network topology. Lists all active
|
|
|
|
|
+nodes, their connections and recent messages.
|
|
|
|
|
+
|
|
|
|
|
+dnetview is based on the design-pattern Model, View, Controller. We
|
|
|
|
|
+create a logical seperation between the underlying data structure or
|
|
|
|
|
+Model; the ui rendering aspect which is the View; and the Controller or
|
|
|
|
|
+game engine that makes everything run.
|
|
|
|
|
+
|
|
|
|
|
+## Version 0.1
|
|
|
|
|
+
|
|
|
|
|
+The current data structure or model of dnetview is this:
|
|
|
|
|
+
|
|
|
|
|
+### Model
|
|
|
|
|
+```
|
|
|
|
|
+ Mutex<HashSet<NodeId>>
|
|
|
|
|
+ Mutex<HashMap<NodeId, NodeInfo>>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### View
|
|
|
|
|
+View is a copy of the model data with additional parameters. We remove
|
|
|
|
|
+the Mutex and add 'ListState' and 'Index' that allow us to use IdList
|
|
|
|
|
+and InfoList as lists.
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+ IdList {
|
|
|
|
|
+ ListState,
|
|
|
|
|
+ HashSet<NodeId>
|
|
|
|
|
+ }
|
|
|
|
|
+ InfoList {
|
|
|
|
|
+ Index,
|
|
|
|
|
+ HashMap<NodeId, NodeInfo>
|
|
|
|
|
+ }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Controller
|
|
|
|
|
+
|
|
|
|
|
+Inside our main function we create two parallel threads: run_rpc and render.
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+Parallel::new() {
|
|
|
|
|
+ run_rpc(model)
|
|
|
|
|
+ render(model)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+run_rpc polls the rpc every 2 seconds. This function updates the
|
|
|
|
|
+underlying model which is protected by mutexes, and detaches in the
|
|
|
|
|
+background.
|
|
|
|
|
+
|
|
|
|
|
+render takes the latest model data and updates the view in a loop.
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+loop {
|
|
|
|
|
+ view = model.update()
|
|
|
|
|
+ }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## Version 0.2:
|
|
|
|
|
+
|
|
|
|
|
+In the first version, we could scroll the list of connected nodes and
|
|
|
|
|
+also scroll a corresponding list of NodeInfo. In the lastest version,
|
|
|
|
|
+the model is made more generic to allow for many types of selectable
|
|
|
|
|
+objects: NodeInfo, SessionInfo, and ConnectInfo.
|
|
|
|
|
+
|
|
|
|
|
+### Model
|
|
|
|
|
+
|
|
|
|
|
+The model has 3 types of SelectableObjects which are organized around
|
|
|
|
|
+an enum:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+enum SelectableObject {
|
|
|
|
|
+ Node(NodeInfo)
|
|
|
|
|
+ Session(SessionInfo)
|
|
|
|
|
+ Connect(ConnectInfo)
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+We copy these values into a Vec<SelectableObject> to use them around the program.
|
|
|
|
|
+
|
|
|
|
|
+### View
|
|
|
|
|
+
|
|
|
|
|
+View is a copy of model without mutex's and with an index that allows the
|
|
|
|
|
+objects to be scrollable lists. We also create a function called render()
|
|
|
|
|
+that draws each window.
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+NodeInfo.render()
|
|
|
|
|
+SessionInfo.render()
|
|
|
|
|
+ConnectInfo.render()
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Controller
|
|
|
|
|
+
|
|
|
|
|
+Like the previous version, we have two functions that run in parallel:
|
|
|
|
|
+run_rpc() and render(). In run_rpc, we poll the rpc and write the new
|
|
|
|
|
+values to the model:
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+ info = NodeInfo::new()...
|
|
|
|
|
+ session = SessionInfo::new()...
|
|
|
|
|
+ connection = ConnectInfo::new()...
|
|
|
|
|
+ model_vec.push(info, session, connection)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+We then continuously update the view with the new data from the model.
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+loop {
|
|
|
|
|
+ view = model.update()
|
|
|
|
|
+}
|
|
|
|
|
+```
|