Browse Source

[2857] Read the notifications from builder threads

Read and clear them from the synchronized queue. Don't act upon them
yet.
Michal 'vorner' Vaner 12 years ago
parent
commit
9136b0a067
2 changed files with 48 additions and 8 deletions
  1. 16 7
      src/bin/memmgr/memmgr.py.in
  2. 32 1
      src/bin/memmgr/tests/memmgr_test.py

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

@@ -124,18 +124,27 @@ class Memmgr(BIND10Server):
         # All copy, switch to the new configuration.
         self._config_params = new_config_params
 
-    def __notify_from_builder(self):
-        # Nothing is implemented here for now. This method should have
-        # code to handle responses from the builder in
-        # self._builder_response_queue[]. Access must be synchronized
-        # using self._builder_lock.
-        pass
+    def _notify_from_builder(self):
+        """
+        Read the notifications from the builder thread.
+        """
+        self._master_sock.recv(1) # Clear the wake-up data
+        notifications = None
+        with self._builder_lock:
+            # Copy the notifications out and clear them from the
+            # original list. We may not assigne [] to
+            # self._builder_response_queue, because there's other
+            # reference to it from the other thread and it would
+            # keep the original list.
+            notifications = self._builder_response_queue[:]
+            del self._builder_response_queue[:]
+        # TODO: Do stuff with the notifications
 
     def __create_builder_thread(self):
         # We get responses from the builder thread on this socket pair.
         (self._master_sock, self._builder_sock) = \
             socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.watch_fileno(self._master_sock, rcallback=self.__notify_from_builder)
+        self.watch_fileno(self._master_sock, rcallback=self._notify_from_builder)
 
         # See the documentation for MemorySegmentBuilder on how the
         # following are used.

+ 32 - 1
src/bin/memmgr/tests/memmgr_test.py

@@ -276,7 +276,38 @@ class TestMemmgr(unittest.TestCase):
         command = ('load', None, dsrc_info, isc.dns.RRClass.IN, 'name')
         self.assertEqual([command], sgmt_info.events)
         self.assertEqual([command], self.__mgr._builder_command_queue)
-        self.__mgr._builder_command_queue.clear()
+        del self.__mgr._builder_command_queue[:]
+
+    def test_notify_from_builder(self):
+        """
+        Check the notify from builder thing eats the notifications and
+        handles them.
+        """
+        # Some mocks
+        class SgmtInfo:
+            pass
+
+        sgmt_info = SgmtInfo
+        class DataSrcInfo:
+            def __init__(self):
+                self.segment_info_map = \
+                    {(isc.dns.RRClass.IN, "name"): sgmt_info}
+        dsrc_info = DataSrcInfo()
+        class Sock:
+            def recv(self, size):
+                pass
+        self.__mgr._master_sock = Sock()
+
+        self.__mgr._builder_lock = threading.Lock()
+        # Extract the reference for the queue. We get a copy of the reference
+        # to check it is cleared, not a new empty one installed
+        notif_ref = self.__mgr._builder_response_queue
+        notif_ref.append(('load-completed', dsrc_info, isc.dns.RRClass.IN,
+                          'name'))
+        # Wake up the main thread and let it process the notifications
+        self.__mgr._notify_from_builder()
+        # All notifications are now eaten
+        self.assertEqual([], notif_ref)
 
 if __name__== "__main__":
     isc.log.resetUnitTestRootLogger()