Merge branch 'lock_manager'

This commit is contained in:
Roberto Rosario
2011-08-23 17:39:27 -04:00
9 changed files with 103 additions and 0 deletions

View File

View File

View File

@@ -0,0 +1,5 @@
from django.conf import settings
DEFAULT_LOCK_TIMEOUT_VALUE = 10
DEFAULT_LOCK_TIMEOUT = getattr(settings, 'LOCK_MANAGER_DEFAULT_LOCK_TIMEOUT', DEFAULT_LOCK_TIMEOUT_VALUE)

View File

@@ -0,0 +1,2 @@
class LockError(Exception):
pass

View File

@@ -0,0 +1,52 @@
try:
from psycopg2 import OperationalError
except ImportError:
class OperationalError(Exception):
pass
import datetime
from django.db.utils import DatabaseError
from django.db.utils import IntegrityError
from django.db import transaction
from django.db import models
from lock_manager.exceptions import LockError
class LockManager(models.Manager):
@transaction.commit_manually
def acquire_lock(self, name, timeout=None):
lock = self.model(name=name, timeout=timeout)
try:
lock.save(force_insert=True)
except IntegrityError:
transaction.rollback()
# There is already an existing lock
# Check it's expiration date and if expired, delete it and
# create it again
lock = self.model.objects.get(name=name)
transaction.rollback()
if datetime.datetime.now() > lock.creation_datetime + datetime.timedelta(seconds=lock.timeout):
self.release_lock(name)
lock.timeout=timeout
lock.save()
transaction.commit()
else:
raise LockError('Unable to acquire lock')
except DatabaseError:
transaction.rollback()
# Special case for ./manage.py syncdb
except (OperationalError, ImproperlyConfigured):
transaction.rollback()
# Special for DjangoZoom, which executes collectstatic media
# doing syncdb and creating the database tables
else:
transaction.commit()
@transaction.commit_manually
def release_lock(self, name):
lock = self.model.objects.get(name=name)
lock.delete()
transaction.commit()

View File

@@ -0,0 +1,26 @@
import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from lock_manager.managers import LockManager
from lock_manager.conf.settings import DEFAULT_LOCK_TIMEOUT
class Lock(models.Model):
creation_datetime = models.DateTimeField(verbose_name=_(u'creation datetime'))
timeout = models.IntegerField(default=DEFAULT_LOCK_TIMEOUT, verbose_name=_(u'timeout'))
name = models.CharField(max_length=32, verbose_name=_(u'name'), unique=True)
objects = LockManager()
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
self.creation_datetime = datetime.datetime.now()
super(Lock, self).save(*args, **kwargs)
class Meta:
verbose_name = _(u'lock')
verbose_name_plural = _(u'locks')

View File

@@ -0,0 +1,16 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)

View File

@@ -0,0 +1 @@
# Create your views here.

View File

@@ -129,6 +129,7 @@ INSTALLED_APPS = (
'project_tools',
'smart_settings',
'navigation',
'lock_manager',
'web_theme',
'common',
'metadata',