summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick White <patrick@patrickwhite.org>2017-12-14 12:10:41 -0800
committerJeff Widman <jeff@jeffwidman.com>2018-03-15 17:00:23 -0700
commit9b0a793e1275b7b031392b66b805b702a1bc58be (patch)
tree2f03196f2ee47c3afefa36b6e2c4d9557f2a4cf9
parent2385079267db0bea6793c4f20588644381803a98 (diff)
downloadkazoo-9b0a793e1275b7b031392b66b805b702a1bc58be.tar.gz
fix (recipe): Don't set creation watch on lock predecessor node
Using exists will register a creation, as well as update and deletion watch on the given node. This introduces a race, where the predecessor node can get deleted between the call to getChildren() and exists(). If that happens, the exists() sets a create watch on a node that will never be created, leaks a create watch.
-rw-r--r--kazoo/recipe/lock.py13
1 files changed, 8 insertions, 5 deletions
diff --git a/kazoo/recipe/lock.py b/kazoo/recipe/lock.py
index ec5d853..95a8272 100644
--- a/kazoo/recipe/lock.py
+++ b/kazoo/recipe/lock.py
@@ -246,11 +246,14 @@ class Lock(object):
predecessor = self.path + "/" + predecessor
self.client.add_listener(self._watch_session)
try:
- if self.client.exists(predecessor, self._watch_predecessor):
- self.wake_event.wait(timeout)
- if not self.wake_event.isSet():
- raise LockTimeout("Failed to acquire lock on %s after "
- "%s seconds" % (self.path, timeout))
+ self.client.get(predecessor, self._watch_predecessor)
+ except NoNodeError:
+ pass # predecessor has already been deleted
+ else:
+ self.wake_event.wait(timeout)
+ if not self.wake_event.isSet():
+ raise LockTimeout("Failed to acquire lock on %s after "
+ "%s seconds" % (self.path, timeout))
finally:
self.client.remove_listener(self._watch_session)