From 599c8438ea9df2f5f68bbb9ff13b7a757080463b Mon Sep 17 00:00:00 2001 From: "K. Noah" Date: Tue, 11 Jan 2011 02:16:06 -0500 Subject: [PATCH 1/2] I added some methods to the default objects manager that allow easier access with the public api. objects.locked(), objects.unlocked(), objects.locked_for(user) ... which could be useful in a number of cases --- locking/managers.py | 29 +++++++++++++++++++++++++++++ locking/models.py | 5 ++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 locking/managers.py diff --git a/locking/managers.py b/locking/managers.py new file mode 100644 index 0000000..1d9d5cf --- /dev/null +++ b/locking/managers.py @@ -0,0 +1,29 @@ +import datetime + +from django.db import models +from django.db.models import Q + +from locking import LOCK_TIMEOUT + +class LockManager(models.Manager): + def locked(self): + timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) + timeout = datetime.datetime.now() - timeout_delta + qs = super(LockManager, self).get_query_set() + qs = qs.filter(_locked_at__gte=timeout) + return qs + + def unlocked(self): + timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) + timeout = datetime.datetime.now() + timeout_delta + qs = super(LockManager, self).get_query_set() + qs = qs.filter(Q(_locked_at__lte=timeout) | Q(_locked_at__isnull=True)) + return qs + + def locked_for(self, user): + timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) + timeout = datetime.datetime.now() - timeout_delta + qs = super(LockManager, self).get_query_set() + qs = qs.filter(_locked_at__gt=timeout) + qs = qs.filter(_locked_by = user) + return qs \ No newline at end of file diff --git a/locking/models.py b/locking/models.py index b3a3f34..7815e34 100644 --- a/locking/models.py +++ b/locking/models.py @@ -7,6 +7,7 @@ from django.contrib.auth import models as auth from locking import LOCK_TIMEOUT, logger +from locking.managers import LockManager class ObjectLockedError(IOError): pass @@ -14,7 +15,9 @@ class ObjectLockedError(IOError): class LockableModel(models.Model): class Meta: abstract = True - + + objects = LockManager() + _locked_at = models.DateTimeField(db_column='locked_at', null=True, editable=False) From 370648542a47bae52f53e0ebde9137bdcb87b659 Mon Sep 17 00:00:00 2001 From: "K. Noah" Date: Wed, 12 Jan 2011 20:53:33 -0500 Subject: [PATCH 2/2] actually working locking managers ... logic failure on the last one --- locking/managers.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/locking/managers.py b/locking/managers.py index 1d9d5cf..37eb392 100644 --- a/locking/managers.py +++ b/locking/managers.py @@ -7,23 +7,22 @@ class LockManager(models.Manager): def locked(self): - timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) - timeout = datetime.datetime.now() - timeout_delta + now = datetime.datetime.now() qs = super(LockManager, self).get_query_set() - qs = qs.filter(_locked_at__gte=timeout) + qs = qs.extra(select={'expires_at':'DATE_ADD(locked_at,INTERVAL 120 SECOND)'}) + qs = qs.extra(where=['DATE_ADD(locked_at,INTERVAL %s SECOND) > %s'], params=[LOCK_TIMEOUT, now]) return qs def unlocked(self): - timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) - timeout = datetime.datetime.now() + timeout_delta + now = datetime.datetime.now() qs = super(LockManager, self).get_query_set() - qs = qs.filter(Q(_locked_at__lte=timeout) | Q(_locked_at__isnull=True)) + qs = qs.extra(select={'expires_at':'DATE_ADD(locked_at,INTERVAL 120 SECOND)'}) + qs = qs.extra(where=['DATE_ADD(locked_at,INTERVAL %s SECOND) < %s or locked_at IS NULL'], params=[LOCK_TIMEOUT, now]) return qs def locked_for(self, user): - timeout_delta = datetime.timedelta(seconds=LOCK_TIMEOUT) - timeout = datetime.datetime.now() - timeout_delta qs = super(LockManager, self).get_query_set() - qs = qs.filter(_locked_at__gt=timeout) + qs = qs.extra(select={'expires_at':'DATE_ADD(locked_at,INTERVAL 120 SECOND)'}) + qs = qs.extra(where=['DATE_ADD(locked_at,INTERVAL %s SECOND) > %s'], params=[LOCK_TIMEOUT, now]) qs = qs.filter(_locked_by = user) return qs \ No newline at end of file