Add a 'can_be_registered' method that checks before notifying

Add a new method that can be used to check if a event type is
allowed to trigger a notification; and initially use it to
disallow the 'ANY' meta event type from being used to trigger
notifications.

Change-Id: I842fcc5d3e06f69a9479b60b3b89a24233171cfb
This commit is contained in:
Joshua Harlow 2014-12-15 16:37:15 -08:00
parent 7dc11bae11
commit 1b0618338c
2 changed files with 33 additions and 1 deletions

View File

@ -38,6 +38,20 @@ class NotifierTest(test.TestCase):
self.assertEqual(2, len(call_collector))
self.assertEqual(1, len(notifier))
def test_notify_not_called(self):
call_collector = []
def call_me(state, details):
call_collector.append((state, details))
notifier = nt.Notifier()
notifier.register(nt.Notifier.ANY, call_me)
notifier.notify(nt.Notifier.ANY, {})
self.assertFalse(notifier.can_trigger_notification(nt.Notifier.ANY))
self.assertEqual(0, len(call_collector))
self.assertEqual(1, len(notifier))
def test_notify_register_deregister(self):
def call_me(state, details):

View File

@ -99,6 +99,9 @@ class Notifier(object):
#: Kleene star constant that is used to recieve all notifications
ANY = '*'
#: Events which can *not* be used to trigger notifications
_DISALLOWED_NOTIFICATION_EVENTS = set([ANY])
def __init__(self):
self._listeners = collections.defaultdict(list)
@ -124,12 +127,20 @@ class Notifier(object):
"""Notify about event occurrence.
All callbacks registered to receive notifications about given
event type will be called.
event type will be called. If the provided event type can not be
used to emit notifications (this is checked via
the :meth:`.can_be_registered` method) then it will silently be
dropped (notification failures are not allowed to cause or
raise exceptions).
:param event_type: event type that occurred
:param details: additional event details *dictionary* passed to
callback keyword argument with the same name.
"""
if not self.can_trigger_notification(event_type):
LOG.debug("Event type '%s' is not allowed to trigger"
" notifications", event_type)
return
listeners = list(self._listeners.get(self.ANY, []))
listeners.extend(self._listeners.get(event_type, []))
if not listeners:
@ -209,6 +220,13 @@ class Notifier(object):
"""Checks if the event can be registered/subscribed to."""
return True
def can_trigger_notification(self, event_type):
"""Checks if the event can trigger a notification."""
if event_type in self._DISALLOWED_NOTIFICATION_EVENTS:
return False
else:
return True
class RestrictedNotifier(Notifier):
"""A notification class that restricts events registered/triggered.