]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: implemented NotificationQueue listener removal
authorRicardo Dias <rdias@suse.com>
Wed, 21 Mar 2018 14:44:22 +0000 (14:44 +0000)
committerRicardo Dias <rdias@suse.com>
Tue, 27 Mar 2018 12:47:36 +0000 (13:47 +0100)
Signed-off-by: Ricardo Dias <rdias@suse.com>
src/pybind/mgr/dashboard/tests/test_notification.py
src/pybind/mgr/dashboard/tools.py

index b421e1eb212602d766a9580fe58f0cd121ce7e11..a25a381d3a33a90fb518c666e494323e01a35a31 100644 (file)
@@ -12,10 +12,6 @@ from ..tools import NotificationQueue
 class Listener(object):
     # pylint: disable=too-many-instance-attributes
     def __init__(self):
-        NotificationQueue.register(self.log_type1, 'type1', priority=90)
-        NotificationQueue.register(self.log_type2, 'type2')
-        NotificationQueue.register(self.log_type1_3, ['type1', 'type3'])
-        NotificationQueue.register(self.log_all, priority=50)
         self.type1 = []
         self.type1_ts = []
         self.type2 = []
@@ -25,6 +21,12 @@ class Listener(object):
         self.all = []
         self.all_ts = []
 
+    def register(self):
+        NotificationQueue.register(self.log_type1, 'type1', priority=90)
+        NotificationQueue.register(self.log_type2, 'type2')
+        NotificationQueue.register(self.log_type1_3, ['type1', 'type3'])
+        NotificationQueue.register(self.log_all, priority=50)
+
         # these should be ignored by the queue
         NotificationQueue.register(self.log_type1, 'type1')
         NotificationQueue.register(self.log_type1_3, ['type1', 'type3'])
@@ -55,6 +57,10 @@ class Listener(object):
         self.type1_3_ts = []
         self.all = []
         self.all_ts = []
+        NotificationQueue.deregister(self.log_type1, 'type1')
+        NotificationQueue.deregister(self.log_type2, 'type2')
+        NotificationQueue.deregister(self.log_type1_3, ['type1', 'type3'])
+        NotificationQueue.deregister(self.log_all)
 
 
 class NotificationQueueTest(unittest.TestCase):
@@ -63,6 +69,9 @@ class NotificationQueueTest(unittest.TestCase):
         cls.listener = Listener()
 
     def setUp(self):
+        self.listener.register()
+
+    def tearDown(self):
         self.listener.clear()
 
     def test_invalid_register(self):
@@ -111,3 +120,19 @@ class NotificationQueueTest(unittest.TestCase):
         self.assertEqual(len(self.listener.type2), 200)
         self.assertEqual(len(self.listener.type1_3), 400)
         self.assertEqual(len(self.listener.all), 600)
+
+    def test_deregister(self):
+        NotificationQueue.start_queue()
+        NotificationQueue.new_notification('type1', 1)
+        NotificationQueue.new_notification('type3', 3)
+        NotificationQueue.stop()
+        self.assertEqual(self.listener.type1, [1])
+        self.assertEqual(self.listener.type1_3, [1, 3])
+
+        NotificationQueue.start_queue()
+        NotificationQueue.deregister(self.listener.log_type1_3, ['type1'])
+        NotificationQueue.new_notification('type1', 4)
+        NotificationQueue.new_notification('type3', 5)
+        NotificationQueue.stop()
+        self.assertEqual(self.listener.type1, [1, 4])
+        self.assertEqual(self.listener.type1_3, [1, 3, 5])
index 73fa4788fd6a9e99391f03f1c7f68862bccc30ed..1f0293a82117541d3f4142a87b0b23bf1bd08d79 100644 (file)
@@ -632,18 +632,47 @@ class NotificationQueue(threading.Thread):
         """
         with cls._lock:
             if not n_types:
-                if not cls._registered_handler(func, cls._ALL_TYPES_):
-                    cls._listeners[cls._ALL_TYPES_].add((priority, func))
-                return
-            if isinstance(n_types, str):
-                if not cls._registered_handler(func, n_types):
-                    cls._listeners[n_types].add((priority, func))
-            elif isinstance(n_types, list):
-                for typ in n_types:
-                    if not cls._registered_handler(func, typ):
-                        cls._listeners[typ].add((priority, func))
-            else:
+                n_types = [cls._ALL_TYPES_]
+            elif isinstance(n_types, str):
+                n_types = [n_types]
+            elif not isinstance(n_types, list):
+                raise Exception("n_types param is neither a string nor a list")
+            for ev_type in n_types:
+                if not cls._registered_handler(func, ev_type):
+                    cls._listeners[ev_type].add((priority, func))
+                    logger.debug("NQ: function %s was registered for events of"
+                                 " type %s", func, ev_type)
+
+    @classmethod
+    def deregister(cls, func, n_types=None):
+        """Removes the listener function from this notification queue
+
+        If the second parameter `n_types` is ommitted, the function is removed
+        from all event types, otherwise the function is removed only for the
+        specified event types.
+
+        Args:
+            func (function): python function
+            n_types (str|list): the single event type, or a list of event types
+        """
+        with cls._lock:
+            if not n_types:
+                n_types = list(cls._listeners.keys())
+            elif isinstance(n_types, str):
+                n_types = [n_types]
+            elif not isinstance(n_types, list):
                 raise Exception("n_types param is neither a string nor a list")
+            for ev_type in n_types:
+                listeners = cls._listeners[ev_type]
+                toRemove = None
+                for pr, fn in listeners:
+                    if fn == func:
+                        toRemove = (pr, fn)
+                        break
+                if toRemove:
+                    listeners.discard(toRemove)
+                    logger.debug("NQ: function %s was deregistered for events "
+                                 "of type %s", func, ev_type)
 
     @classmethod
     def new_notification(cls, notify_type, notify_value):