[Checkins] SVN: zc.zk/trunk/s - Added support for discovering and testing ephemeral addresses using
jim
cvs-admin at zope.org
Fri Jun 22 15:28:05 UTC 2012
Log message for revision 127018:
- Added support for discovering and testing ephemeral addresses using
zc.monitor. See ``monitor.test`` for details.
Changed:
U zc.zk/trunk/setup.py
U zc.zk/trunk/src/zc/zk/README.txt
A zc.zk/trunk/src/zc/zk/monitor.py
A zc.zk/trunk/src/zc/zk/monitor.test
A zc.zk/trunk/src/zc/zk/monitor.zcml
U zc.zk/trunk/src/zc/zk/tests.py
-=-
Modified: zc.zk/trunk/setup.py
===================================================================
--- zc.zk/trunk/setup.py 2012-06-22 13:31:09 UTC (rev 127017)
+++ zc.zk/trunk/setup.py 2012-06-22 15:28:01 UTC (rev 127018)
@@ -16,7 +16,7 @@
install_requires = ['setuptools', 'zc.thread']
extras_require = dict(
test=['zope.testing', 'zc-zookeeper-static', 'mock', 'manuel',
- 'zope.event', 'netifaces'],
+ 'zope.event', 'netifaces', 'zope.component', 'zc.monitor'],
static=['zc-zookeeper-static'],
)
Modified: zc.zk/trunk/src/zc/zk/README.txt
===================================================================
--- zc.zk/trunk/src/zc/zk/README.txt 2012-06-22 13:31:09 UTC (rev 127017)
+++ zc.zk/trunk/src/zc/zk/README.txt 2012-06-22 15:28:01 UTC (rev 127018)
@@ -1165,12 +1165,15 @@
Change History
==============
-0.9.0 (2012-06-21)
+0.9.0 (2012-06-22)
------------------
-- Fixed: The ZooKeeper logging sometimes generated lots of spurious
- empty log messages.
+- Added support for discovering and testing ephemeral addresses using
+ zc.monitor. See ``monitor.test`` for details.
+- Fixed: The ZooKeeper logging bridge sometimes generated lots of
+ spurious empty log messages.
+
0.8.0 (2012-05-15)
------------------
Added: zc.zk/trunk/src/zc/zk/monitor.py
===================================================================
--- zc.zk/trunk/src/zc/zk/monitor.py (rev 0)
+++ zc.zk/trunk/src/zc/zk/monitor.py 2012-06-22 15:28:01 UTC (rev 127018)
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# Copyright (c) 2011 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.
+#
+##############################################################################
+
+import json
+import sys
+
+_servers = []
+
+def notify(event):
+ _servers.append(dict(address=event.name, path=event.path,
+ **event.properties))
+
+def servers(connection, path=None):
+ if path is None:
+ connection.write(json.dumps(_servers) + '\n')
+ else:
+ connection.write(
+ ' '.join([s['address'] for s in _servers if s['path'] == path])
+ + '\n')
+
+def _connect(addr):
+ import re
+ import socket
+
+ if re.search(':\d+$', addr):
+ host, port = addr.rsplit(':')
+ addr = host, int(port)
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ else:
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+
+ sock.connect(addr)
+ return sock
+
+def check(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+ [addr, path] = args
+
+ sock = _connect(addr)
+
+ sock.sendall('servers %s\n' % path)
+ f = sock.makefile()
+ addr = f.readline()
+
+ f.close()
+ sock.close()
+
+ _connect(addr).close()
+
+def get_addr(args=None):
+ if args is None:
+ args = sys.argv[1:]
+
+
+ [addr, path] = args
+
+ sock = _connect(addr)
+ f = sock.makefile()
+ sock.sendall('servers %s\n' % path)
+ print f.readline(),
Property changes on: zc.zk/trunk/src/zc/zk/monitor.py
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Added: zc.zk/trunk/src/zc/zk/monitor.test
===================================================================
--- zc.zk/trunk/src/zc/zk/monitor.test (rev 0)
+++ zc.zk/trunk/src/zc/zk/monitor.test 2012-06-22 15:28:01 UTC (rev 127018)
@@ -0,0 +1,99 @@
+zc.monitor plugin for reportint on servers registered by a process
+==================================================================
+
+Sometimes, when deploying a process that registers servers listening
+on ephemeral ports, we need to be able to find out what the parts
+(addresses) are. Looking at the ZooKeeper tree may not be convenient
+if there are multiple servers.
+
+Th zc.zk.monitor modules provides a zc.monitor plugin that can be
+subscribed to zc.zk.RegisteringServer events and then used in a
+zc.monitor server to report on registered servers.
+
+ >>> import sys, zc.zk.monitor, zc.zk
+
+ >>> zc.zk.monitor.notify(zc.zk.RegisteringServer(
+ ... '1.2.3.4:8080', '/foo/bar', dict(pid=42)))
+
+ >>> zc.zk.monitor.servers(sys.stdout)
+ [{"path": "/foo/bar", "pid": 42, "address": "1.2.3.4:8080"}]
+
+It outputs a list of server objects as a JSON string.
+
+ >>> zc.zk.monitor.notify(zc.zk.RegisteringServer(
+ ... '1.2.3.4:8081', '/foo/baz', dict(pid=42)))
+
+ >>> zc.zk.monitor.servers(sys.stdout) # doctest: +NORMALIZE_WHITESPACE
+ [{"path": "/foo/bar", "pid": 42, "address": "1.2.3.4:8080"},
+ {"path": "/foo/baz", "pid": 42, "address": "1.2.3.4:8081"}]
+
+If you specify a path, then only the address with that path will be
+output as a string (not json):
+
+ >>> zc.zk.monitor.servers(sys.stdout, '/foo/bar')
+ 1.2.3.4:8080
+
+Helper scripts
+==============
+
+``zc.zk.monitor`` provides two helper scripts. They aren't registered
+as setuptools entry points, as they are only useful for servers that
+use zc.monitor.
+
+zc.zk.monitor.check
+-------------------
+
+The check script (entry-point) takes a monitor address and a path,
+connects to the monitor server to get the address registered for a
+monitor, and connects to the address. This can be used to check
+whether a server is up and running (or at least accepting
+connections).
+
+We'll test it by starting a server, registering it and checking it:
+
+ >>> import socket, zc.monitor, zc.thread, sys
+ >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ >>> s.bind(('', 0))
+ >>> s.listen(1)
+
+ >>> _, server_port = s.getsockname()
+ >>> _, monitor_port = zc.monitor.start(('', 0))
+ >>> zc.monitor.register(zc.zk.monitor.servers, 'servers')
+ >>> zc.zk.monitor.notify(zc.zk.RegisteringServer(
+ ... ':%s' % server_port, '/test/server', dict(pid=42)))
+
+ >>> zc.zk.monitor.check((':%s /test/server' % monitor_port).split())
+
+Here, check simply returned. Now, if we stop our server:
+
+ >>> s.close()
+
+check will error:
+
+ >>> zc.zk.monitor.check((':%s /test/server' % monitor_port).split())
+ Traceback (most recent call last):
+ ...
+ error: [Errno 111] Connection refused
+
+This will, of course, cause it to exit with a non-zero status when run
+as an actual script.
+
+zc.zk.monitor.get_addr
+----------------------
+
+The get_addrscript simply prints the address it got from the monitor:
+
+ >>> zc.zk.monitor.get_addr((':%s /test/server' % monitor_port).split())
+ :37327
+
+This can be used to get the address to pass it to some other process.
+
+.. cleanup
+
+ >>> import zope.component
+ >>> zope.component.getSiteManager().unregisterUtility(
+ ... zc.zk.monitor.servers,
+ ... zc.monitor.interfaces.IMonitorPlugin, 'servers')
+ True
+
+ >>> zc.monitor.last_listener.close()
Property changes on: zc.zk/trunk/src/zc/zk/monitor.test
___________________________________________________________________
Added: svn:eol-style
+ native
Added: zc.zk/trunk/src/zc/zk/monitor.zcml
===================================================================
--- zc.zk/trunk/src/zc/zk/monitor.zcml (rev 0)
+++ zc.zk/trunk/src/zc/zk/monitor.zcml 2012-06-22 15:28:01 UTC (rev 127018)
@@ -0,0 +1,12 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+<include package="zope.component" />
+
+<subscriber for="zc.zk.RegisteringServer" handler="zc.zk.monitor.notify" />
+
+<utility provides="zc.monitor.interfaces.IMonitorPlugin"
+ name="servers"
+ component="zc.zk.monitor.servers"
+ />
+
+</configure>
Property changes on: zc.zk/trunk/src/zc/zk/monitor.zcml
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: zc.zk/trunk/src/zc/zk/tests.py
===================================================================
--- zc.zk/trunk/src/zc/zk/tests.py 2012-06-22 13:31:09 UTC (rev 127017)
+++ zc.zk/trunk/src/zc/zk/tests.py 2012-06-22 15:28:01 UTC (rev 127018)
@@ -1557,6 +1557,12 @@
setUp=zc.zk.testing.setUp, tearDown=zc.zk.testing.tearDown,
checker=checker,
),
+ doctest.DocFileSuite(
+ 'monitor.test',
+ checker = zope.testing.renormalizing.RENormalizing([
+ (re.compile(':\d+'), ':9999'),
+ ])
+ ),
))
if not zc.zk.testing.testing_with_real_zookeeper():
suite.addTest(unittest.makeSuite(Tests))
More information about the checkins
mailing list