From b010f4fc14c0d016b268b45d4950d88d39be9227 Mon Sep 17 00:00:00 2001 From: wil paredes Date: Fri, 6 Jun 2014 01:24:18 -0700 Subject: restore default Lock token storage, add toggle to make it thread-local * add thread_local=False parameter to Lock.__init__() and StrictRedis.lock() * use thread_local to decide whether to put token in thread-local storage --- redis/client.py | 10 ++++++++-- redis/lock.py | 11 +++++++++-- redis/utils.py | 7 +++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/redis/client.py b/redis/client.py index 2abd675..ef360ff 100755 --- a/redis/client.py +++ b/redis/client.py @@ -478,7 +478,7 @@ class StrictRedis(object): continue def lock(self, name, timeout=None, sleep=0.1, blocking_timeout=None, - lock_class=None): + lock_class=None, thread_local=False): """ Return a new Lock object using key ``name`` that mimics the behavior of threading.Lock. @@ -496,6 +496,11 @@ class StrictRedis(object): float or integer, both representing the number of seconds to wait. ``lock_class`` forces the specified lock implementation. + + ``thread_local`` indicates whether the lock token is placed in + thread-local storage. Setting this to True may be necessary if + multiple execution contexts (such as threads or coroutines) share + a single Lock instance within a process. Defaults to False. """ if lock_class is None: if self._use_lua_lock is None: @@ -508,7 +513,8 @@ class StrictRedis(object): self._use_lua_lock = False lock_class = self._use_lua_lock and LuaLock or Lock return lock_class(self, name, timeout=timeout, sleep=sleep, - blocking_timeout=blocking_timeout) + blocking_timeout=blocking_timeout, + thread_local=thread_local) def pubsub(self, **kwargs): """ diff --git a/redis/lock.py b/redis/lock.py index adf90e0..7d4a9b3 100644 --- a/redis/lock.py +++ b/redis/lock.py @@ -2,6 +2,7 @@ import threading import time as mod_time import uuid from redis.exceptions import LockError, WatchError +from redis.utils import dummy from redis._compat import b @@ -14,7 +15,7 @@ class Lock(object): multiple clients play nicely together. """ def __init__(self, redis, name, timeout=None, sleep=0.1, - blocking=True, blocking_timeout=None): + blocking=True, blocking_timeout=None, thread_local=False): """ Create a new Lock instance named ``name`` using the Redis client supplied by ``redis``. @@ -38,6 +39,11 @@ class Lock(object): spend trying to acquire the lock. A value of ``None`` indicates continue trying forever. ``blocking_timeout`` can be specified as a float or integer, both representing the number of seconds to wait. + + ``thread_local`` indicates whether the lock token is placed in + thread-local storage. Setting this to True may be necessary if + multiple execution contexts (such as threads or coroutines) share + a single Lock instance within a process. Defaults to False. """ self.redis = redis self.name = name @@ -45,7 +51,8 @@ class Lock(object): self.sleep = sleep self.blocking = blocking self.blocking_timeout = blocking_timeout - self.local = threading.local() + self.thread_local = bool(thread_local) + self.local = threading.local() if self.thread_local else dummy() self.local.token = None if self.timeout and self.sleep > self.timeout: raise LockError("'sleep' must be less than 'timeout'") diff --git a/redis/utils.py b/redis/utils.py index e10d20f..0b0067e 100644 --- a/redis/utils.py +++ b/redis/utils.py @@ -24,3 +24,10 @@ def pipeline(redis_obj): p = redis_obj.pipeline() yield p p.execute() + + +class dummy(object): + """ + Instances of this class can be used as an attribute container. + """ + pass -- cgit v1.2.1