##// END OF EJS Templates
caches: improved locking problems with distributed lock new cache backend
super-admin -
r4714:97b167f6 default
parent child Browse files
Show More
@@ -10,7 +10,7 b' from redis import StrictRedis'
10 __version__ = '3.7.0'
10 __version__ = '3.7.0'
11
11
12 loggers = {
12 loggers = {
13 k: getLogger("rhodecode" + ".".join((__name__, k)))
13 k: getLogger("rhodecode." + ".".join((__name__, k)))
14 for k in [
14 for k in [
15 "acquire",
15 "acquire",
16 "refresh.thread.start",
16 "refresh.thread.start",
@@ -221,10 +221,11 b' class Lock(object):'
221 """
221 """
222 logger = loggers["acquire"]
222 logger = loggers["acquire"]
223
223
224 logger.debug("Getting %r ...", self._name)
224 logger.debug("Getting acquire on %r ...", self._name)
225
225
226 if self._held:
226 if self._held:
227 raise AlreadyAcquired("Already acquired from this Lock instance.")
227 owner_id = self.get_owner_id()
228 raise AlreadyAcquired("Already acquired from this Lock instance. Lock id: {}".format(owner_id))
228
229
229 if not blocking and timeout is not None:
230 if not blocking and timeout is not None:
230 raise TimeoutNotUsable("Timeout cannot be used if blocking=False")
231 raise TimeoutNotUsable("Timeout cannot be used if blocking=False")
@@ -287,17 +287,16 b' class BaseRedisBackend(redis_backend.Red'
287
287
288 def get_mutex(self, key):
288 def get_mutex(self, key):
289 if self.distributed_lock:
289 if self.distributed_lock:
290 import redis_lock
291 lock_key = redis_backend.u('_lock_{0}').format(key)
290 lock_key = redis_backend.u('_lock_{0}').format(key)
292 log.debug('Trying to acquire Redis lock for key %s', lock_key)
291 log.debug('Trying to acquire Redis lock for key %s', lock_key)
293 lock = redis_lock.Lock(
292
294 redis_client=self.client,
293 auto_renewal = True
295 name=lock_key,
294 lock_timeout = self.lock_timeout
296 expire=self.lock_timeout,
295 if auto_renewal and not self.lock_timeout:
297 auto_renewal=False,
296 # set default timeout for auto_renewal
298 strict=True,
297 lock_timeout = 10
299 )
298 return get_mutex_lock(self.client, lock_key, lock_timeout,
300 return lock
299 auto_renewal=auto_renewal)
301 else:
300 else:
302 return None
301 return None
303
302
@@ -310,3 +309,34 b' class RedisPickleBackend(PickleSerialize'
310 class RedisMsgPackBackend(MsgPackSerializer, BaseRedisBackend):
309 class RedisMsgPackBackend(MsgPackSerializer, BaseRedisBackend):
311 key_prefix = 'redis_msgpack_backend'
310 key_prefix = 'redis_msgpack_backend'
312 pass
311 pass
312
313
314 def get_mutex_lock(client, lock_key, lock_timeout, auto_renewal=False):
315 import redis_lock
316
317 class _RedisLockWrapper(object):
318 """LockWrapper for redis_lock"""
319
320 def __init__(self):
321 pass
322
323 @property
324 def lock(self):
325 return redis_lock.Lock(
326 redis_client=client,
327 name=lock_key,
328 expire=lock_timeout,
329 auto_renewal=auto_renewal,
330 strict=True,
331 )
332
333 def acquire(self, wait=True):
334 return self.lock.acquire(wait)
335
336 def release(self):
337 try:
338 self.lock.release()
339 except redis_lock.NotAcquired:
340 pass
341
342 return _RedisLockWrapper()
General Comments 0
You need to be logged in to leave comments. Login now