Permalink
Browse files

Merge pull request #8 from jeloou/master

Using transactions in Mutex.
  • Loading branch information...
kiddouk committed Oct 16, 2012
2 parents 7907b59 + f96b30f commit fc141d86071aaf86e62282f1e64e8d1721da4287
Showing with 18 additions and 17 deletions.
  1. +16 −17 redisco/models/base.py
  2. +2 −0 redisco/models/exceptions.py
View
@@ -6,7 +6,7 @@
from attributes import *
from key import Key
from managers import ManagerDescriptor, Manager
-from exceptions import FieldValidationError, MissingID, BadKeyError
+from exceptions import FieldValidationError, MissingID, BadKeyError, WatchError
from attributes import Counter
__all__ = ['Model', 'from_key']
@@ -739,10 +739,6 @@ def from_key(key):
class Mutex(object):
- """Implements locking so that other instances may not modify it.
-
- Code ported from Ohm.
- """
def __init__(self, instance):
self.instance = instance
@@ -755,18 +751,21 @@ def __exit__(self, exc_type, exc_value, traceback):
def lock(self):
o = self.instance
- while not o.db.setnx(o.key('_lock'), self.lock_timeout):
- lock = o.db.get(o.key('_lock'))
- if not lock:
- continue
- if not self.lock_has_expired(lock):
- time.sleep(0.5)
- continue
- lock = o.db.getset(o.key('_lock'), self.lock_timeout)
- if not lock:
- break
- if self.lock_has_expired(lock):
- break
+ _lock_key = o.key('_lock')
+ with o.db.pipeline() as pipe:
+ while True:
+ try:
+ pipe.watch(_lock_key)
+ if o.db.exists(_lock_key) and not self.lock_has_expired(o.db.get(_lock_key)):
+ continue
+
+ pipe.multi()
+ pipe.set(_lock_key, self.lock_timeout).execute()
+ break
+
+ except WatchError:
+ time.sleep(0.5)
+ continue
def lock_has_expired(self, lock):
return float(lock) < time.time()
@@ -1,6 +1,8 @@
##########
# ERRORS #
##########
+from redis import WatchError
+
class Error(StandardError):
pass

0 comments on commit fc141d8

Please sign in to comment.