summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-07-29 08:10:46 +0000
committerGerrit Code Review <review@openstack.org>2016-07-29 08:10:46 +0000
commit115a39a3cf0275fb9f9f8d56cf06220ce1864fee (patch)
treeb64475a6e252ea08c4dc4fc3c3516e3f4c9bb11a
parentd6b710fe1badd8aa0d6df1d10d314470bd815b76 (diff)
parente5c530a2cdd1fefbe468d9ac8d8eb8ceed4ec262 (diff)
downloadtooz-1.42.0.tar.gz
Merge "etcd: don't run heartbeat() concurrently"1.42.0
-rw-r--r--tooz/drivers/etcd.py12
1 files changed, 12 insertions, 0 deletions
diff --git a/tooz/drivers/etcd.py b/tooz/drivers/etcd.py
index 4ff93f3..bdfa35c 100644
--- a/tooz/drivers/etcd.py
+++ b/tooz/drivers/etcd.py
@@ -13,7 +13,9 @@
# under the License.
import logging
+import threading
+import fasteners
from oslo_utils import encodeutils
from oslo_utils import timeutils
import requests
@@ -94,11 +96,18 @@ class EtcdLock(locking.Lock):
self._lock_url = lock_url
self._node = None
+ # NOTE(jschwarz): this lock is mainly used to prevent concurrent runs
+ # of hearthbeat() with another function. For more details, see
+ # https://bugs.launchpad.net/python-tooz/+bug/1603005.
+ self._lock = threading.Lock()
+
@_translate_failures
+ @fasteners.locked
def break_(self):
reply = self.client.delete(self._lock_url, make_url=False)
return reply.get('errorCode') is None
+ @fasteners.locked
def acquire(self, blocking=True):
blocking, timeout = utils.convert_blocking(blocking)
if timeout is not None:
@@ -141,6 +150,7 @@ class EtcdLock(locking.Lock):
return False
@_translate_failures
+ @fasteners.locked
def release(self):
if self in self.coord._acquired_locks:
lock_url = self._lock_url
@@ -157,6 +167,7 @@ class EtcdLock(locking.Lock):
return False
@_translate_failures
+ @fasteners.locked
def heartbeat(self):
"""Keep the lock alive."""
poked = self.client.put(self._lock_url,
@@ -167,6 +178,7 @@ class EtcdLock(locking.Lock):
LOG.warning("Unable to heartbeat by updating key '%s' with "
"extended expiry of %s seconds: %d, %s", self.name,
self.ttl, errorcode, poked.get("message"))
+ self._node = poked['node']
class EtcdDriver(coordination.CoordinationDriver):