From 2bb9b76c01019f3c82776429c07d34bd1c439f2b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 22 Jan 2009 08:03:37 +0000 Subject: If no subscribers are registered via ``registerHandler`` or ``registerSubscriptionAdapter``, ``notify`` is a noop for speed. --- CHANGES.txt | 10 +++++++--- repoze/bfg/registry.py | 22 +++++++++++++++++++--- repoze/bfg/tests/test_registry.py | 33 ++++++++++++++++++++++++++------- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8c6be8eb8..d2c31903f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -14,10 +14,14 @@ Implementation Changes - Tease out an extra 4% performance boost by changing the Router; instead of using imported ZCA APIs, use the same APIs directly - against the registry that is an attribute of the Router. As a - result, the registry used by BFG is now a subclass of + against the registry that is an attribute of the Router. + +- The registry used by BFG is now a subclass of ``zope.component.registry.Components`` (defined as - ``repoze.bfg.registry.Registry``); it has a ``notify`` method. + ``repoze.bfg.registry.Registry``); it has a ``notify`` method, a + ``registerSubscriptionAdapter`` and a ``registerHandler`` method. + If no subscribers are registered via ``registerHandler`` or + ``registerSubscriptionAdapter``, ``notify`` is a noop for speed. 0.6.3 (2009-01-19) ================== diff --git a/repoze/bfg/registry.py b/repoze/bfg/registry.py index d1dff6744..b9a74d885 100644 --- a/repoze/bfg/registry.py +++ b/repoze/bfg/registry.py @@ -25,10 +25,26 @@ deprecated( ) class Registry(Components): + + # for optimization purposes, if no listeners are listening, don't try + # to notify them + _has_listeners = False + + def registerSubscriptionAdapter(self, *arg, **kw): + result = Components.registerSubscriptionAdapter(self, *arg, **kw) + self._has_listeners = True + return result + + def registerHandler(self, *arg, **kw): + result = Components.registerHandler(self, *arg, **kw) + self._has_listeners = True + return result + def notify(self, *events): - # iterating over subscribers assures they get executed - for ignored in self.subscribers(events, None): - pass + if self._has_listeners: + # iterating over subscribers assures they get executed + for ignored in self.subscribers(events, None): + pass class ThreadLocalRegistryManager(threading.local): def __init__(self): diff --git a/repoze/bfg/tests/test_registry.py b/repoze/bfg/tests/test_registry.py index 2c26d850e..f54ac934f 100644 --- a/repoze/bfg/tests/test_registry.py +++ b/repoze/bfg/tests/test_registry.py @@ -10,15 +10,34 @@ class TestRegistry(unittest.TestCase): def _makeOne(self): return self._getTargetClass()() - def test_notify(self): + def test_registerHandler_and_notify(self): registry = self._makeOne() + self.assertEqual(registry._has_listeners, False) + from zope.interface import Interface + from zope.interface import implements + class IFoo(Interface): + pass + class FooEvent(object): + implements(IFoo) L = [] - def subscribers(events, *arg): - L.extend(events) - return ['abc'] - registry.subscribers = subscribers - registry.notify('123') - self.assertEqual(L, ['123']) + def f(event): + L.append(event) + registry.registerHandler(f, [IFoo]) + self.assertEqual(registry._has_listeners, True) + event = FooEvent() + registry.notify(event) + self.assertEqual(L, [event]) + + def test_registerSubscriptionAdapter_and_notify(self): + registry = self._makeOne() + self.assertEqual(registry._has_listeners, False) + from zope.interface import Interface + class EventHandler: + pass + class IFoo(Interface): + pass + registry.registerSubscriptionAdapter(EventHandler, [IFoo], Interface) + self.assertEqual(registry._has_listeners, True) class TestPopulateRegistry(unittest.TestCase): def setUp(self): -- cgit v1.2.3