diff --git a/tooz/coordination.py b/tooz/coordination.py index 3c79f3b5..eb504f88 100644 --- a/tooz/coordination.py +++ b/tooz/coordination.py @@ -194,7 +194,11 @@ class CoordinationDriver(object): :param callback: The function that was executed when a member joined this group """ - self._hooks_join_group[group_id].remove(callback) + try: + self._hooks_join_group[group_id].remove(callback) + except ValueError: + raise WatchCallbackNotFound(group_id, callback) + if (not self._has_hooks_for_group(group_id) and group_id in self._group_members): del self._group_members[group_id] @@ -221,7 +225,11 @@ class CoordinationDriver(object): :param callback: The function that was executed when a member left this group """ - self._hooks_leave_group[group_id].remove(callback) + try: + self._hooks_leave_group[group_id].remove(callback) + except ValueError: + raise WatchCallbackNotFound(group_id, callback) + if (not self._has_hooks_for_group(group_id) and group_id in self._group_members): del self._group_members[group_id] @@ -252,7 +260,11 @@ class CoordinationDriver(object): group """ - self._hooks_elected_leader[group_id].remove(callback) + try: + self._hooks_elected_leader[group_id].remove(callback) + except ValueError: + raise WatchCallbackNotFound(group_id, callback) + if not self._hooks_elected_leader[group_id]: del self._hooks_elected_leader[group_id] @@ -611,6 +623,21 @@ class GroupNotEmpty(ToozError): super(GroupNotEmpty, self).__init__("Group %s is not empty" % group_id) +class WatchCallbackNotFound(ToozError): + """Exception raised when unwatching a group. + + Raised when the caller tries to unwatch a group with a callback that + does not exist. + + """ + def __init__(self, group_id, callback): + self.group_id = group_id + self.callback = callback + super(WatchCallbackNotFound, self).__init__( + 'Callback %s is not registered on group %s' % + (callback.__name__, group_id)) + + class SerializationError(ToozError): "Exception raised when serialization or deserialization breaks." diff --git a/tooz/tests/test_coordination.py b/tooz/tests/test_coordination.py index 4ef11084..589e78cd 100644 --- a/tooz/tests/test_coordination.py +++ b/tooz/tests/test_coordination.py @@ -671,6 +671,24 @@ class TestAPI(testscenarios.TestWithScenarios, self._coord.unwatch_elected_as_leader(self.group_id, self._set_event) self.assertEqual(0, len(self._coord._hooks_elected_leader)) + def test_unwatch_elected_as_leader_callback_not_found(self): + self._coord.create_group(self.group_id).get() + self.assertRaises(tooz.coordination.WatchCallbackNotFound, + self._coord.unwatch_elected_as_leader, + self.group_id, lambda x: None) + + def test_unwatch_join_group_callback_not_found(self): + self._coord.create_group(self.group_id).get() + self.assertRaises(tooz.coordination.WatchCallbackNotFound, + self._coord.unwatch_join_group, + self.group_id, lambda x: None) + + def test_unwatch_leave_group_callback_not_found(self): + self._coord.create_group(self.group_id).get() + self.assertRaises(tooz.coordination.WatchCallbackNotFound, + self._coord.unwatch_leave_group, + self.group_id, lambda x: None) + def test_get_lock(self): lock = self._coord.get_lock(self._get_random_uuid()) self.assertTrue(lock.acquire())