summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwil paredes <code@dystedium.com>2014-06-06 01:24:18 -0700
committerwil paredes <code@dystedium.com>2014-06-06 01:24:18 -0700
commitb010f4fc14c0d016b268b45d4950d88d39be9227 (patch)
treeea2fb3b8ba9ac91899a93cf13906b3ceabd1c318
parent318bab78eba9e3a5cc7f93f3e865ecb2e05cba76 (diff)
downloadredis-py-b010f4fc14c0d016b268b45d4950d88d39be9227.tar.gz
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
-rwxr-xr-xredis/client.py10
-rw-r--r--redis/lock.py11
-rw-r--r--redis/utils.py7
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