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

dnet: cleanup and add TODOs. also don't crash if a node goes offline.

lunar-mining 2 лет назад
Родитель
Сommit
52b172ece7
3 измененных файлов с 130 добавлено и 115 удалено
  1. 12 6
      bin/dnet/main.py
  2. 5 0
      bin/dnet/model.py
  3. 113 109
      bin/dnet/view.py

+ 12 - 6
bin/dnet/main.py

@@ -53,9 +53,13 @@ class Dnetview:
         while True:
             await asyncio.sleep(0.01)
             data = await rpc.reader.readline()
-            data = json.loads(data)
-            info[name] = data
-            await self.queue.put(info)
+            try:
+                data = json.loads(data)
+                info[name] = data
+                await self.queue.put(info)
+            except:
+                info[name] = {}
+                await self.queue.put(info)
 
         await rpc.dnet_switch(False)
         await rpc.stop()
@@ -79,13 +83,16 @@ class Dnetview:
         while True:
             info = await self.queue.get()
             values = list(info.values())[0]
-            method = values.get("method")
+            try:
+                method = values.get("method")
+            except:
+                self.model.add_offline(info)
+                continue
 
             if method == "dnet.subscribe_events":
                 self.model.add_event(info)
             else:
                 self.model.add_node(info)
-
             self.queue.task_done()
 
     def main(self):
@@ -101,7 +108,6 @@ class Dnetview:
 
         self.ev.create_task(self.start_connect_slots(nodes))
         self.ev.create_task(self.view.update_view(self.ev, loop))
-        self.ev.create_task(self.view.render_info(self.ev, loop))
 
         loop.run()
 

+ 5 - 0
bin/dnet/model.py

@@ -72,6 +72,11 @@ class Model:
             id = channel["id"]
             url = channel["url"]
             self.nodes[name]['manual'][f"{id}"] = url
+    
+    def add_offline(self, node):
+        name = list(node.keys())[0]
+        values = list(node.values())[0]
+        self.nodes[name] = values
 
     def add_event(self, event):
         name = list(event.keys())[0]

+ 113 - 109
bin/dnet/view.py

@@ -40,6 +40,9 @@ class DnetWidget(urwid.WidgetWrap):
         self._w = urwid.AttrWrap(self._w, None)
         self._w.focus_attr = 'line'
 
+    def is_empty(self):
+        self.is_empty == True
+
 
 class Node(DnetWidget):
     def set_txt(self):
@@ -83,11 +86,102 @@ class View():
         columns = urwid.Columns([leftbox, rightbox], focus_column=0)
         self.ui = urwid.Frame(urwid.AttrWrap( columns, 'body' ))
 
+    #-----------------------------------------------------------------
+    # Render get_info()
+    #-----------------------------------------------------------------
+    def draw_info(self, node_name, info):
+       node = Node(node_name, "node")
+       node.set_txt()
+       self.listwalker.contents.append(node)
+
+       if info['outbound']:
+           session = Session(node_name, "outbound")
+           session.set_txt()
+           self.listwalker.contents.append(session)
+           for i, addr in info['outbound'].items():
+               slot = Slot(node_name, "outbound-slot")
+               slot.set_txt(i, addr)
+               self.listwalker.contents.append(slot)
+
+       if info['inbound']:
+           session = Session(node_name, "inbound")
+           session.set_txt()
+           self.listwalker.contents.append(session)
+           for i, addr in info['inbound'].items():
+               slot = Slot(node_name, "inbound-slot")
+               slot.set_txt(i, addr)
+               self.listwalker.contents.append(slot)
+
+       if info['manual']:
+           session = Session(node_name, "manual")
+           session.set_txt()
+           self.listwalker.contents.append(session)
+           for i, addr in info['manual'].items():
+               slot = Slot(node_name, "manual-slot")
+               slot.set_txt(i, addr)
+               self.listwalker.contents.append(slot)
+
+       if info['seed']:
+           session = Session(node_name, "seed")
+           session.set_txt()
+           self.listwalker.contents.append(session)
+           for i, info in info['seed'].items():
+               slot = Slot(node_name, "seed-slot")
+               slot.set_txt(i, addr)
+               self.listwalker.contents.append(slot)
+
+    #-----------------------------------------------------------------
+    # Render subscribe_events() (left menu)
+    #-----------------------------------------------------------------
+    def fill_left_box(self):
+        known_inbound = []
+        new_inbound= {}
+        for index, item in enumerate(self.listwalker.contents):
+            # Update outbound slot info
+            if item.session == "outbound-slot":
+                key = (f"{item.node_name}", f"{item.i}")
+                if key in self.model.nodes[item.node_name]['event']:
+                    info = self.model.nodes[item.node_name]['event'].get(key)
+                    slot = Slot(item.node_name, item.session)
+                    slot.set_txt(item.i, info)
+                    self.listwalker.contents[index] = slot
+
+    #-----------------------------------------------------------------
+    # Render subscribe_events() (right menu)
+    #-----------------------------------------------------------------
+    def fill_right_box(self):
+        self.pile.contents.clear()
+        focus_w = self.list.get_focus()
+        session = focus_w[0].session
+
+        if session == "outbound":
+            key = (focus_w[0].node_name, "outbound")
+            info = self.model.nodes.get(focus_w[0].node_name)
+            if key in info['event']:
+                ev = info['event'].get(key)
+                self.pile.contents.append((
+                    urwid.Text(f" {ev}"),
+                    self.pile.options()))
+
+        if (session == "outbound-slot" or session == "inbound-slot"
+                or session == "manual-slot" or session == "seed-slot"):
+            addr = focus_w[0].addr
+            node_name = focus_w[0].node_name
+            info = self.model.nodes.get(node_name)
+            if addr in info['msgs']:
+                msg = info['msgs'].get(addr)
+                for m in msg:
+                    time = m[0]
+                    event = m[1]
+                    msg = m[2]
+                    self.pile.contents.append((urwid.Text(
+                            f"{time}: {event}: {msg}"),
+                            self.pile.options()))
 
     async def update_view(self, evloop: asyncio.AbstractEventLoop,
                           loop: urwid.MainLoop):
         known_nodes = []
-        known_inbound = []
+        off_nodes = []
         while True:
             await asyncio.sleep(0.1)
             # Redraw the screen
@@ -96,115 +190,25 @@ class View():
             for index, item in enumerate(self.listwalker.contents):
                 known_nodes.append(item.node_name)
 
-            #-----------------------------------------------------------------
-            # Render get_info()
-            #-----------------------------------------------------------------
+            for node_name, info in self.model.nodes.items():
+                if not info:
+                    off_nodes.append(node_name)
+                
+            # TODO:
+            # Right now we ignore info if it's in the set of known nodes.
+            # However, there are a few events that should trigger a redraw:
+            #   * a new inbound connection comes online
+            #   * a new node comes online (FIXME)
+            #   * a known node has gone offline
+            #   * a inbound connection has gone offline
+            #   * when RPC can't connect, display the node as offline.
             for node_name, info in self.model.nodes.items():
                 if node_name in known_nodes:
                     continue
-                else:
-                    node = Node(node_name, "node")
-                    node.set_txt()
-                    self.listwalker.contents.append(node)
-
-                    if info['outbound']:
-                        session = Session(node_name, "outbound")
-                        session.set_txt()
-                        self.listwalker.contents.append(session)
-                        for i, addr in info['outbound'].items():
-                            slot = Slot(node_name, "outbound-slot")
-                            slot.set_txt(i, addr)
-                            self.listwalker.contents.append(slot)
-
-                    if info['inbound']:
-                        session = Session(node_name, "inbound")
-                        session.set_txt()
-                        self.listwalker.contents.append(session)
-                        for i, addr in info['inbound'].items():
-                            slot = Slot(node_name, "inbound-slot")
-                            slot.set_txt(i, addr)
-                            self.listwalker.contents.append(slot)
-
-                    if info['manual']:
-                        session = Session(node_name, "manual")
-                        session.set_txt()
-                        self.listwalker.contents.append(session)
-                        for i, addr in info['manual'].items():
-                            slot = Slot(node_name, "manual-slot")
-                            slot.set_txt(i, addr)
-                            self.listwalker.contents.append(slot)
-
-                    if info['seed']:
-                        session = Session(node_name, "seed")
-                        session.set_txt()
-                        self.listwalker.contents.append(session)
-                        for i, info in info['seed'].items():
-                            slot = Slot(node_name, "seed-slot")
-                            slot.set_txt(i, addr)
-                            self.listwalker.contents.append(slot)
-
-           #-----------------------------------------------------------------
-           # Render subscribe_events() (left menu)
-           #-----------------------------------------------------------------
-            new_inbound = {}
-            for index, item in enumerate(self.listwalker.contents):
-                # Update outbound slot info
-                if item.session == "outbound-slot":
-                    key = (f"{item.node_name}", f"{item.i}")
-                    if key in self.model.nodes[item.node_name]['event']:
-                        info = self.model.nodes[item.node_name]['event'].get(key)
-                        slot = Slot(item.node_name, item.session)
-                        slot.set_txt(item.i, info)
-                        self.listwalker.contents[index] = slot
-                # Get known inbounds
-                if item.session == "inbound-slot":
-                    if item.i not in known_inbound:
-                        known_inbound.append(item.i)
-                # Get unknown inbounds
-                inbound = self.model.nodes[item.node_name]['inbound']
-                for i, addr in inbound.items():
-                    if i in known_inbound:
-                        continue
-                    else:
-                        new_inbound[i] = (addr, item.node_name)
-                # TODO: update new inbounds
-
-
-    # Render subscribe_events() (right menu)
-    async def render_info(self, evloop: asyncio.AbstractEventLoop,
-                          loop: urwid.MainLoop):
-        while True:
-            await asyncio.sleep(0.01)
-            # Redraw the screen
-            evloop.call_soon(loop.draw_screen)
-
-            self.pile.contents.clear()
-            focus_w = self.list.get_focus()
-            if focus_w[0] is None:
-                continue
-            else:
-                session = focus_w[0].session
-                if session == "node":
+                if node_name in off_nodes:
                     continue
-                if session == "outbound":
-                    key = (focus_w[0].node_name, "outbound")
-                    info = self.model.nodes.get(focus_w[0].node_name)
-                    if key in info['event']:
-                        ev = info['event'].get(key)
-                        self.pile.contents.append((
-                            urwid.Text(f" {ev}"),
-                            self.pile.options()))
-                if (session == "outbound-slot" or session == "inbound-slot"
-                        or session == "manual-slot" or session == "seed-slot"):
-                    addr = focus_w[0].addr
-                    node_name = focus_w[0].node_name
-                    info = self.model.nodes.get(node_name)
-                    if addr in info['msgs']:
-                        msg = info['msgs'].get(addr)
-                        for m in msg:
-                            time = m[0]
-                            event = m[1]
-                            msg = m[2]
-                            self.pile.contents.append((urwid.Text(
-                                    f"{time}: {event}: {msg}"),
-                                    self.pile.options()))
+                else:
+                    self.draw_info(node_name, info)
+                
+            self.fill_left_box()
+            self.fill_right_box()