[Checkins] SVN: zc.zk/trunk/src/zc/zk/ Added ``walk`` and ``is_ephemeral`` methods.
Jim Fulton
jim at zope.com
Fri Jan 27 18:00:03 UTC 2012
Log message for revision 124218:
Added ``walk`` and ``is_ephemeral`` methods.
Fixed testing: When running with a real ZooKeeper server, the
(virtual) root didn't have a ``zookeeper`` node.
Changed:
U zc.zk/trunk/src/zc/zk/README.txt
U zc.zk/trunk/src/zc/zk/__init__.py
U zc.zk/trunk/src/zc/zk/testing.py
U zc.zk/trunk/src/zc/zk/tests.py
-=-
Modified: zc.zk/trunk/src/zc/zk/README.txt
===================================================================
--- zc.zk/trunk/src/zc/zk/README.txt 2012-01-27 16:59:08 UTC (rev 124217)
+++ zc.zk/trunk/src/zc/zk/README.txt 2012-01-27 18:00:02 UTC (rev 124218)
@@ -845,7 +845,58 @@
specifing access control lists. Use the ``--help`` option to see how
to use it.
+Iterating over a tree
+=====================
+The ``walk`` method can be used to walk over the nodes in a tree:
+
+ >>> for path in zk.walk():
+ ... print path
+ /
+ /cms
+ /cms/databases
+ /cms/providers
+ /cms/providers/1.2.3.4:5
+ /databases
+ /databases/cms
+ /fooservice
+ /fooservice/providers
+ /fooservice/providers/192.168.0.42:8080
+ /fooservice/providers/192.168.0.42:8081
+ /fooservice/providers/192.168.0.42:8082
+ /fooservice/provision
+ /fooservice/provision/node1
+ /fooservice/provision/node2
+ /lb
+ /lb/pools
+ /lb/pools/cms
+ /zookeeper
+ /zookeeper/quota
+
+ >>> for path in zk.walk('/fooservice'):
+ ... print path
+ /fooservice
+ /fooservice/providers
+ /fooservice/providers/192.168.0.42:8080
+ /fooservice/providers/192.168.0.42:8081
+ /fooservice/providers/192.168.0.42:8082
+ /fooservice/provision
+ /fooservice/provision/node1
+ /fooservice/provision/node2
+
+Modifications to nodes are reflected while traversing:
+
+ >>> for path in zk.walk('/fooservice'):
+ ... print path
+ ... if 'provision' in zk.get_children(path):
+ ... zk.delete_recursive(path+'/provision')
+ /fooservice
+ /fooservice/providers
+ /fooservice/providers/192.168.0.42:8080
+ /fooservice/providers/192.168.0.42:8081
+ /fooservice/providers/192.168.0.42:8082
+
+
Graph analysis
==============
@@ -969,6 +1020,9 @@
Boolean, defaulting to false, indicating whether to do a dry
run of the import, without applying any changes.
+``is_ephemeral(path)``
+ Return ``True`` if the node at ``path`` is ephemeral,``False`` otherwise.
+
``ln(source, destination)``
Create a symbolic link at the destination path pointing to the
source path.
@@ -1006,6 +1060,9 @@
``resolve(path)``
Find the real path for the given path.
+``walk(path)``
+ Iterate over the nodes of a tree rooted at path.
+
In addition, ``ZooKeeper`` instances provide access to the following
ZooKeeper functions as methods: ``acreate``, ``add_auth``,
``adelete``, ``aexists``, ``aget``, ``aget_acl``, ``aget_children``,
@@ -1104,13 +1161,18 @@
Change History
==============
-0.6.1 (2012-01-27)
+0.7.0 (2012-01-27)
------------------
+- Added ``walk`` and ``is_ephemeral`` methods.
+
- Fixed testing: There were spurious errors when closing a testing
ZooKeeper connection in which ephemeral nodes were created and when
they were deleted by another session.
+- Fixed testing: When running with a real ZooKeeper server, the
+ (virtual) root didn't have a ``zookeeper`` node.
+
0.6.0 (2012-01-25)
------------------
Modified: zc.zk/trunk/src/zc/zk/__init__.py
===================================================================
--- zc.zk/trunk/src/zc/zk/__init__.py 2012-01-27 16:59:08 UTC (rev 124217)
+++ zc.zk/trunk/src/zc/zk/__init__.py 2012-01-27 18:00:02 UTC (rev 124218)
@@ -461,7 +461,7 @@
print "%s not deleted due to ephemeral descendent." % path
return ephemeral_child
- ephemeral = self.get(path)[1]['ephemeralOwner'] and not force
+ ephemeral = self.is_ephemeral(path) and not force
if dry_run:
if ephemeral:
print "wouldn't delete %s because it's ephemeral." % path
@@ -475,6 +475,9 @@
self.delete(path)
return ephemeral
+ def is_ephemeral(self, path):
+ return bool(self.get(path)[1]['ephemeralOwner'])
+
def export_tree(self, path='/', ephemeral=False, name=None):
output = []
out = output.append
@@ -521,7 +524,6 @@
def _set(self, path, data):
return self.set(path, data)
-
def ln(self, target, source):
base, name = source.rsplit('/', 1)
if target[-1] == '/':
@@ -540,6 +542,15 @@
return zookeeper.CONNECTING_STATE
return zookeeper.state(self.handle)
+ def walk(self, path='/'):
+ yield path
+ for name in sorted(self.get_children(path)):
+ if path != '/':
+ name = '/'+name
+ for p in self.walk(path+name):
+ yield p
+
+
def _make_method(name):
return (lambda self, *a, **kw:
getattr(zookeeper, name)(self.handle, *a, **kw))
Modified: zc.zk/trunk/src/zc/zk/testing.py
===================================================================
--- zc.zk/trunk/src/zc/zk/testing.py 2012-01-27 16:59:08 UTC (rev 124217)
+++ zc.zk/trunk/src/zc/zk/testing.py 2012-01-27 18:00:02 UTC (rev 124218)
@@ -59,7 +59,8 @@
if time.time() > deadline:
raise AssertionError('timeout')
-def setup_tree(tree, connection_string, root='/test-root'):
+def setup_tree(tree, connection_string, root='/test-root',
+ zookeeper_node=False):
zk = zc.zk.ZooKeeper(connection_string)
if zk.exists(root):
zk.delete_recursive(root)
@@ -71,6 +72,13 @@
threads = 1
favorite_color = 'red'
""", root)
+
+ if zookeeper_node:
+ zk.import_tree("""
+ /zookeeper
+ /quota
+ """, root)
+
zk.close()
def testing_with_real_zookeeper():
@@ -126,7 +134,7 @@
if real_zk:
test_root = '/zc.zk.testing.test-root%s' % random.randint(0, sys.maxint)
globs['/zc.zk.testing.test-root'] = test_root
- setup_tree(tree, real_zk, test_root)
+ setup_tree(tree, real_zk, test_root, True)
orig_init = zookeeper.init
cm = mock.patch('zookeeper.init')
Modified: zc.zk/trunk/src/zc/zk/tests.py
===================================================================
--- zc.zk/trunk/src/zc/zk/tests.py 2012-01-27 16:59:08 UTC (rev 124217)
+++ zc.zk/trunk/src/zc/zk/tests.py 2012-01-27 18:00:02 UTC (rev 124218)
@@ -1450,6 +1450,18 @@
>>> zk.close()
"""
+def is_ephemeral():
+ """
+ >>> zk = zc.zk.ZooKeeper('zookeeper.example.com:2181')
+ >>> zk.register_server('/fooservice/providers', 'a:b')
+ >>> zk.is_ephemeral('/fooservice')
+ False
+ >>> zk.is_ephemeral('/fooservice/providers')
+ False
+ >>> zk.is_ephemeral('/fooservice/providers/a:b')
+ True
+ >>> zk.close()
+ """
# XXX
# deleting linked node
More information about the checkins
mailing list