From 1bdd531a185ff10258c885cc6a0affea84c3e28f Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Fri, 21 Mar 2014 16:12:56 +0100 Subject: [PATCH] coordination: raise GroupNotCreated when watching uncreated group Change-Id: I5da2bcd8a764a12cb1ec02e68dd947b69e230e4a Co-Authored-By: Sahid Ferdjaoui --- tooz/drivers/zookeeper.py | 27 +++++++++++++++++++++------ tooz/tests/test_coordination.py | 14 ++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/tooz/drivers/zookeeper.py b/tooz/drivers/zookeeper.py index fe651b79..2dc03064 100644 --- a/tooz/drivers/zookeeper.py +++ b/tooz/drivers/zookeeper.py @@ -241,8 +241,11 @@ class KazooDriver(BaseZooKeeperDriver): # Initialize the current member list self._group_members[group_id] = get_members_req.get() - self._coord.ChildrenWatch(self._path_group(group_id), - on_children_change) + try: + self._coord.ChildrenWatch(self._path_group(group_id), + on_children_change) + except exceptions.NoNodeError: + raise coordination.GroupNotCreated(group_id) def watch_join_group(self, group_id, callback): # Check if we already have hooks for this group_id, if not, start @@ -255,12 +258,18 @@ class KazooDriver(BaseZooKeeperDriver): group_id, callback) if not already_being_watched: - self._watch_group(group_id) + try: + self._watch_group(group_id) + except Exception: + # Rollback and unregister the hook + self.unwatch_join_group(group_id, callback) + raise def unwatch_join_group(self, group_id, callback): super(BaseZooKeeperDriver, self).unwatch_join_group( group_id, callback) - if not self._has_hooks_for_group(group_id): + if (not self._has_hooks_for_group(group_id) + and group_id in self._group_members): del self._group_members[group_id] def watch_leave_group(self, group_id, callback): @@ -274,12 +283,18 @@ class KazooDriver(BaseZooKeeperDriver): group_id, callback) if not already_being_watched: - self._watch_group(group_id) + try: + self._watch_group(group_id) + except Exception: + # Rollback and unregister the hook + self.unwatch_leave_group(group_id, callback) + raise def unwatch_leave_group(self, group_id, callback): super(BaseZooKeeperDriver, self).unwatch_leave_group( group_id, callback) - if not self._has_hooks_for_group(group_id): + if (not self._has_hooks_for_group(group_id) + and group_id in self._group_members): del self._group_members[group_id] def run_watchers(self): diff --git a/tooz/tests/test_coordination.py b/tooz/tests/test_coordination.py index d1b6d66b..789e8dc4 100644 --- a/tooz/tests/test_coordination.py +++ b/tooz/tests/test_coordination.py @@ -336,6 +336,20 @@ class TestAPI(testscenarios.TestWithScenarios, self._coord.run_watchers() self.assertIsNone(self.event) + def test_watch_join_group_non_existent(self): + self.assertRaises(tooz.coordination.GroupNotCreated, + self._coord.watch_join_group, + self.group_id, + lambda: None) + self.assertEqual(0, len(self._coord._hooks_join_group[self.group_id])) + + def test_watch_leave_group_non_existent(self): + self.assertRaises(tooz.coordination.GroupNotCreated, + self._coord.watch_leave_group, + self.group_id, + lambda: None) + self.assertEqual(0, len(self._coord._hooks_leave_group[self.group_id])) + @staticmethod def _get_random_uuid(): return str(uuid.uuid4()).encode('ascii')