[Checkins] SVN: zc.zk/trunk/s ``zc.zk.RegisteringServer`` events are generated during server

Jim Fulton jim at zope.com
Fri Dec 9 10:27:34 UTC 2011


Log message for revision 123645:
  ``zc.zk.RegisteringServer`` events are generated during server
  registration to allow third-party libraries to record additional
  properties on new server nodes.
  

Changed:
  U   zc.zk/trunk/setup.py
  U   zc.zk/trunk/src/zc/zk/README.txt
  U   zc.zk/trunk/src/zc/zk/__init__.py
  A   zc.zk/trunk/src/zc/zk/event.py
  U   zc.zk/trunk/src/zc/zk/tests.py

-=-
Modified: zc.zk/trunk/setup.py
===================================================================
--- zc.zk/trunk/setup.py	2011-12-09 09:44:53 UTC (rev 123644)
+++ zc.zk/trunk/setup.py	2011-12-09 10:27:33 UTC (rev 123645)
@@ -15,7 +15,8 @@
 
 install_requires = ['setuptools', 'zc.thread']
 extras_require = dict(
-    test=['zope.testing', 'zc-zookeeper-static', 'mock', 'manuel'],
+    test=['zope.testing', 'zc-zookeeper-static', 'mock', 'manuel',
+          'zope.event'],
     static=['zc-zookeeper-static'],
     )
 

Modified: zc.zk/trunk/src/zc/zk/README.txt
===================================================================
--- zc.zk/trunk/src/zc/zk/README.txt	2011-12-09 09:44:53 UTC (rev 123644)
+++ zc.zk/trunk/src/zc/zk/README.txt	2011-12-09 10:27:33 UTC (rev 123645)
@@ -76,7 +76,9 @@
 When registering a server, you can optionally provide server (node)
 data as additional keyword arguments to register_server.  By default,
 the process id is set as the ``pid`` property.  This is useful to
-tracking down the server process.
+tracking down the server process.  In addition, an event is generated,
+providing subscribers to add properties as a server is being
+registered. (See `Server-registration events`_.)
 
 Get the addresses of service providers
 ======================================
@@ -545,6 +547,19 @@
 It would be bad, in practice, to remove a node that processes are
 watching.
 
+Server-registration events
+==========================
+
+When ``register_server`` is called, a ``zc.zk.RegisteringServer``
+event is emmitted with a properties attribute that can be updated by
+subscribers prior to creating the ZooKeeper ephemeral node.  This
+allows third-party code to record extra server information.
+
+Events are emitted by passing them to ``zc.zk.event.notify``. If
+``zope.event`` is installed, then ``zc.zk.event.notify`` is an alias
+for ``zope.event.notify``, otherwise, ``zc.zk.event.notify`` is an
+empty function that can be replaced by applications.
+
 ZooKeeper Session Management
 ============================
 
@@ -766,6 +781,10 @@
 - Fixed bug: Ephemeral nodes weren't recreated when sessions were
   reestablished.
 
+- ``zc.zk.RegisteringServer`` events are generated during server
+  registration to allow third-party libraries to record additional
+  properties on new server nodes.
+
 - Added a testing module that provides ZooKeeper emulation for
   testing complex interactions with zc.zk without needing a running
   ZooKeeper server.

Modified: zc.zk/trunk/src/zc/zk/__init__.py
===================================================================
--- zc.zk/trunk/src/zc/zk/__init__.py	2011-12-09 09:44:53 UTC (rev 123644)
+++ zc.zk/trunk/src/zc/zk/__init__.py	2011-12-09 10:27:33 UTC (rev 123645)
@@ -20,6 +20,7 @@
 import threading
 import time
 import weakref
+import zc.zk.event
 import zc.thread
 import zookeeper
 
@@ -167,6 +168,7 @@
             addr = '%s:%s' % addr
         self.connected.wait(self.timeout)
         path = self.resolve(path)
+        zc.zk.event.notify(RegisteringServer(addr, path, kw))
         self.create(path + '/' + addr, encode(kw), acl, zookeeper.EPHEMERAL)
 
     test_sleep = 0
@@ -736,3 +738,27 @@
         self.children = children
         for name, child in children.iteritems():
             child.name = name
+
+class RegisteringServer:
+    """Event emitted while a server is being registered.
+
+    Attributes:
+
+    name
+      The server name (node name)
+    name
+      The service path (node parent path)
+    properties
+      A dictionary of properties to be saved on the ephemeral node.
+
+      Typeically, subscribers will add properties.
+    """
+
+    def __init__(self, name, path, properties):
+        self.name = name
+        self.path = path
+        self.properties = properties
+
+    def __repr__(self):
+        return "RegisteringServer(%r, %r, %r)" % (
+            self.name, self.path, self.properties)

Added: zc.zk/trunk/src/zc/zk/event.py
===================================================================
--- zc.zk/trunk/src/zc/zk/event.py	                        (rev 0)
+++ zc.zk/trunk/src/zc/zk/event.py	2011-12-09 10:27:33 UTC (rev 123645)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+__all__ = ['notify']
+
+def notify(event):
+    """NOOP event-notification hook
+
+    Replace this with your own handler, or, better yet, install zope.event.
+    """
+_noop = notify
+
+try:
+    from zope.event import notify
+except ImportError:
+    pass


Property changes on: zc.zk/trunk/src/zc/zk/event.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Modified: zc.zk/trunk/src/zc/zk/tests.py
===================================================================
--- zc.zk/trunk/src/zc/zk/tests.py	2011-12-09 09:44:53 UTC (rev 123644)
+++ zc.zk/trunk/src/zc/zk/tests.py	2011-12-09 10:27:33 UTC (rev 123645)
@@ -972,6 +972,40 @@
     >>> zk.close()
     """
 
+def test_server_registeration_event():
+    """
+    >>> import sys, zc.zk.event, zope.event
+    >>> zc.zk.event.notify is zope.event.notify
+    True
+    >>> sys.modules['zope.event'] = None
+    >>> _ = reload(zc.zk.event)
+    >>> zc.zk.event.notify is zope.event.notify
+    False
+    >>> zc.zk.event.notify is zc.zk.event._noop
+    True
+    >>> def notify(e):
+    ...     print e
+    ...     e.properties['test'] = 1
+    >>> zc.zk.event.notify = notify
+
+    >>> zk = zc.zk.ZooKeeper('zookeeper.example.com:2181')
+    >>> zk.register_server('/fooservice/providers', '1.2.3.4:5678')
+    RegisteringServer('1.2.3.4:5678', '/fooservice/providers', {'pid': 1793})
+
+    >>> zk.print_tree('/fooservice/providers')
+    /providers
+      /1.2.3.4:5678
+        pid = 1793
+        test = 1
+
+    >>> zk.close()
+
+    >>> sys.modules['zope.event'] = zope.event
+    >>> _ = reload(zc.zk.event)
+    >>> zc.zk.event.notify is zope.event.notify
+    True
+    """
+
 event = threading.Event()
 def check_async(show=True, expected_status=0):
     event.clear()
@@ -993,6 +1027,7 @@
 def test_suite():
     checker = zope.testing.renormalizing.RENormalizing([
         (re.compile('pid = \d+'), 'pid = 9999'),
+        (re.compile("{'pid': \d+}"), 'pid = 9999'),
         (re.compile('/zc\.zk\.testing\.test-root\d+'), ''),
         (re.compile(r'2 None\n4 None'), '4 None\n2 None'),
         ])



More information about the checkins mailing list