Commits

Lx Yu committed a3a248c

refine redis backend lock.
- use the lock in redis client instead.
- add lock_timeout and lock_sleep arguments support

  • Participants
  • Parent commits b323546

Comments (0)

Files changed (1)

File dogpile/cache/backends/redis.py

 from __future__ import absolute_import
 from dogpile.cache.api import CacheBackend, NO_VALUE
 from dogpile.cache.compat import pickle
-import random
-import time
 
 redis = None
 
      When left at False, dogpile will coordinate on a regular
      threading mutex.
 
+    :param lock_timeout: integer, number of seconds after acquiring a lock that
+     Redis should expire it.
+
+    :param lock_sleep: integer, number of seconds to sleep when failed to
+     acquire a lock.
+
     """
 
     def __init__(self, arguments):
         self.port = arguments.pop('port', 6379)
         self.db = arguments.pop('db', 0)
         self.distributed_lock = arguments.get('distributed_lock', False)
+        self.lock_timeout = arguments.get('lock_timeout', None)
+        self.lock_sleep = arguments.get('lock_sleep', 0.1)
         self.redis_expiration_time = arguments.pop('redis_expiration_time', 0)
         self.client = self._create_client()
 
 
     def get_mutex(self, key):
         if self.distributed_lock:
-            return RedisLock(lambda: self.client, key)
+            return self.client.lock(u"_lock{}".format(key), self.lock_timeout,
+                                    self.lock_sleep)
         else:
             return None
 
         for key in keys:
             pipe.delete(key)
         pipe.execute()
-
-class RedisLock(object):
-    """Simple distributed lock using Redis.
-
-    This is an adaptation of the memcached lock featured at
-    http://amix.dk/blog/post/19386
-
-    """
-    def __init__(self, client_fn, key):
-        self.client_fn = client_fn
-        self.key = "_lock" + key
-
-    def acquire(self, wait=True):
-        client = self.client_fn()
-        i = 0
-        while True:
-            if client.setnx(self.key, 1):
-                return True
-            elif not wait:
-                return False
-            else:
-                sleep_time = (((i + 1) * random.random()) + 2 ** i) / 2.5
-                time.sleep(sleep_time)
-            if i < 15:
-                i += 1
-
-    def release(self):
-        client = self.client_fn()
-        client.delete(self.key)
-
-