Browse Source

[2857] Handle the load-complete notification

Michal 'vorner' Vaner 11 years ago
parent
commit
c65345a086
2 changed files with 53 additions and 9 deletions
  1. 24 7
      src/bin/memmgr/memmgr.py.in
  2. 29 2
      src/bin/memmgr/tests/memmgr_test.py

+ 24 - 7
src/bin/memmgr/memmgr.py.in

@@ -124,6 +124,14 @@ class Memmgr(BIND10Server):
         # All copy, switch to the new configuration.
         self._config_params = new_config_params
 
+    def _cmd_to_builder(self, cmd):
+        """
+        Send a command to the builder, with proper synchronization.
+        """
+        with self._builder_cv:
+            self._builder_command_queue.append(cmd)
+            self._builder_cv.notify_all()
+
     def _notify_from_builder(self):
         """
         Read the notifications from the builder thread.
@@ -138,7 +146,20 @@ class Memmgr(BIND10Server):
             # keep the original list.
             notifications = self._builder_response_queue[:]
             del self._builder_response_queue[:]
-        # TODO: Do stuff with the notifications
+        while notifications:
+            notification = notifications.pop()
+            notif_name = notification[0]
+            if notif_name == 'load-completed':
+                (_, dsrc_info, rrclass, dsrc_name) = notification
+                sgmt_info = dsrc_info.segment_info_map[(rrclass, dsrc_name)]
+                cmd = sgmt_info.complete_update()
+                if cmd is not None:
+                    self._cmd_to_builder(cmd)
+                else:
+                    pass
+                    # TODO: Send to the readers, #2858
+            else:
+                raise ValueError('Unknown notification name: ' + notif_name)
 
     def __create_builder_thread(self):
         # We get responses from the builder thread on this socket pair.
@@ -170,9 +191,7 @@ class Memmgr(BIND10Server):
 
         # This makes the MemorySegmentBuilder exit its main loop. It
         # should make the builder thread joinable.
-        with self._builder_cv:
-            self._builder_command_queue.append(('shutdown',))
-            self._builder_cv.notify_all()
+        self._cmd_to_builder(('shutdown',))
 
         self._builder_thread.join()
 
@@ -228,9 +247,7 @@ class Memmgr(BIND10Server):
             send_cmd = sgmt_info.start_update()
             assert cmd == send_cmd and sgmt_info.get_state() == \
                 SegmentInfo.UPDATING
-            with self._builder_cv:
-                self._builder_command_queue.append(cmd)
-                self._builder_cv.notify()
+            self._cmd_to_builder(cmd)
 
 if '__main__' == __name__:
     mgr = Memmgr()

+ 29 - 2
src/bin/memmgr/tests/memmgr_test.py

@@ -285,8 +285,8 @@ class TestMemmgr(unittest.TestCase):
         """
         # Some mocks
         class SgmtInfo:
-            pass
-
+            def complete_update():
+                return 'command'
         sgmt_info = SgmtInfo
         class DataSrcInfo:
             def __init__(self):
@@ -297,6 +297,10 @@ class TestMemmgr(unittest.TestCase):
             def recv(self, size):
                 pass
         self.__mgr._master_sock = Sock()
+        commands = []
+        def mock_cmd_to_builder(cmd):
+            commands.append(cmd)
+        self.__mgr._cmd_to_builder = mock_cmd_to_builder
 
         self.__mgr._builder_lock = threading.Lock()
         # Extract the reference for the queue. We get a copy of the reference
@@ -308,6 +312,29 @@ class TestMemmgr(unittest.TestCase):
         self.__mgr._notify_from_builder()
         # All notifications are now eaten
         self.assertEqual([], notif_ref)
+        self.assertEqual(['command'], commands)
+        del commands[:]
+        # The new command is sent
+        # Once again the same, but with the last command - nothing new pushed
+        sgmt_info.complete_update = lambda: None
+        notif_ref.append(('load-completed', dsrc_info, isc.dns.RRClass.IN,
+                          'name'))
+        self.__mgr._notify_from_builder()
+        self.assertEqual([], notif_ref)
+        self.assertEqual([], commands)
+        # This is invalid (unhandled) notification name
+        notif_ref.append(('unhandled',))
+        self.assertRaises(ValueError, self.__mgr._notify_from_builder)
+        self.assertEqual([], notif_ref)
+
+    def test_send_to_builder(self):
+        """
+        Send command to the builder test.
+        """
+        self.__mgr._builder_cv = threading.Condition()
+        self.__mgr._cmd_to_builder(('test',))
+        self.assertEqual([('test',)], self.__mgr._builder_command_queue)
+        del self.__mgr._builder_command_queue[:]
 
 if __name__== "__main__":
     isc.log.resetUnitTestRootLogger()