Skip to content

Commit e096928

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Mutex access to local lock attributes"
2 parents 908040b + f125c6a commit e096928

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed

nodepool/zk/zookeeper.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import abc
1616
import json
1717
import logging
18+
import threading
1819
import time
1920
import uuid
2021

@@ -394,6 +395,9 @@ class NodeRequest(BaseModel):
394395
def __init__(self, id=None):
395396
super(NodeRequest, self).__init__(id)
396397
self.lock = None
398+
# Local thread lock that is acquired when we are manipulating
399+
# the ZK lock.
400+
self._thread_lock = threading.Lock()
397401
self.declined_by = []
398402
self.node_types = []
399403
self.nodes = []
@@ -510,6 +514,9 @@ def __init__(self, id=None):
510514
super(Node, self).__init__(id)
511515
# Local lock object; not serialized
512516
self.lock = None
517+
# Local thread lock that is acquired when we are manipulating
518+
# the ZK lock.
519+
self._thread_lock = threading.Lock()
513520
# Cached list of lock contenders; not serialized (and possibly
514521
# not up to date; use for status listings only).
515522
self.lock_contenders = set()
@@ -2138,22 +2145,23 @@ def lockNodeRequest(self, request, blocking=True, timeout=None):
21382145
log = get_annotated_logger(self.log, event_id=request.event_id,
21392146
node_request_id=request.id)
21402147
path = self._requestLockPath(request.id)
2141-
try:
2142-
lock = Lock(self.kazoo_client, path)
2143-
have_lock = lock.acquire(blocking, timeout)
2144-
except kze.LockTimeout:
2145-
raise npe.TimeoutException(
2146-
"Timeout trying to acquire lock %s" % path)
2147-
except kze.NoNodeError:
2148-
have_lock = False
2149-
log.error("Request not found for locking: %s", request)
2148+
with request._thread_lock:
2149+
try:
2150+
lock = Lock(self.kazoo_client, path)
2151+
have_lock = lock.acquire(blocking, timeout)
2152+
except kze.LockTimeout:
2153+
raise npe.TimeoutException(
2154+
"Timeout trying to acquire lock %s" % path)
2155+
except kze.NoNodeError:
2156+
have_lock = False
2157+
log.error("Request not found for locking: %s", request)
21502158

2151-
# If we aren't blocking, it's possible we didn't get the lock
2152-
# because someone else has it.
2153-
if not have_lock:
2154-
raise npe.ZKLockException("Did not get lock on %s" % path)
2159+
# If we aren't blocking, it's possible we didn't get the lock
2160+
# because someone else has it.
2161+
if not have_lock:
2162+
raise npe.ZKLockException("Did not get lock on %s" % path)
21552163

2156-
request.lock = lock
2164+
request.lock = lock
21572165

21582166
# Do an in-place update of the node request so we have the latest data
21592167
self.updateNodeRequest(request)
@@ -2171,8 +2179,9 @@ def unlockNodeRequest(self, request):
21712179
if request.lock is None:
21722180
raise npe.ZKLockException(
21732181
"Request %s does not hold a lock" % request)
2174-
request.lock.release()
2175-
request.lock = None
2182+
with request._thread_lock:
2183+
request.lock.release()
2184+
request.lock = None
21762185

21772186
def lockNode(self, node, blocking=True, timeout=None,
21782187
ephemeral=True, identifier=None):
@@ -2199,22 +2208,23 @@ def lockNode(self, node, blocking=True, timeout=None,
21992208
and could not get the lock, or a lock is already held.
22002209
'''
22012210
path = self._nodeLockPath(node.id)
2202-
try:
2203-
lock = Lock(self.kazoo_client, path, identifier)
2204-
have_lock = lock.acquire(blocking, timeout, ephemeral)
2205-
except kze.LockTimeout:
2206-
raise npe.TimeoutException(
2207-
"Timeout trying to acquire lock %s" % path)
2208-
except kze.NoNodeError:
2209-
have_lock = False
2210-
self.log.error("Node not found for locking: %s", node)
2211+
with node._thread_lock:
2212+
try:
2213+
lock = Lock(self.kazoo_client, path, identifier)
2214+
have_lock = lock.acquire(blocking, timeout, ephemeral)
2215+
except kze.LockTimeout:
2216+
raise npe.TimeoutException(
2217+
"Timeout trying to acquire lock %s" % path)
2218+
except kze.NoNodeError:
2219+
have_lock = False
2220+
self.log.error("Node not found for locking: %s", node)
22112221

2212-
# If we aren't blocking, it's possible we didn't get the lock
2213-
# because someone else has it.
2214-
if not have_lock:
2215-
raise npe.ZKLockException("Did not get lock on %s" % path)
2222+
# If we aren't blocking, it's possible we didn't get the lock
2223+
# because someone else has it.
2224+
if not have_lock:
2225+
raise npe.ZKLockException("Did not get lock on %s" % path)
22162226

2217-
node.lock = lock
2227+
node.lock = lock
22182228

22192229
# Do an in-place update of the node so we have the latest data.
22202230
self.updateNode(node)
@@ -2231,8 +2241,9 @@ def unlockNode(self, node):
22312241
'''
22322242
if node.lock is None:
22332243
raise npe.ZKLockException("Node %s does not hold a lock" % node)
2234-
node.lock.release()
2235-
node.lock = None
2244+
with node._thread_lock:
2245+
node.lock.release()
2246+
node.lock = None
22362247

22372248
def forceUnlockNode(self, node):
22382249
'''

0 commit comments

Comments
 (0)