diff options
author | Patrick White <patrick@patrickwhite.org> | 2017-12-14 12:10:41 -0800 |
---|---|---|
committer | Jeff Widman <jeff@jeffwidman.com> | 2018-03-15 17:00:23 -0700 |
commit | 9b0a793e1275b7b031392b66b805b702a1bc58be (patch) | |
tree | 2f03196f2ee47c3afefa36b6e2c4d9557f2a4cf9 | |
parent | 2385079267db0bea6793c4f20588644381803a98 (diff) | |
download | kazoo-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.py | 13 |
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) |