diff --git a/apps/lock_manager/__init__.py b/apps/lock_manager/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/lock_manager/models.py b/apps/lock_manager/models.py new file mode 100644 index 0000000000..56a2d3e483 --- /dev/null +++ b/apps/lock_manager/models.py @@ -0,0 +1,54 @@ +import datetime + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.db.utils import IntegrityError +from django.db import transaction + + +class LockError(Exception): + pass + +class LockManager(models.Manager): + @transaction.commit_manually + def acquire_lock(self, name): + lock = self.model(name=name) + 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 + # re-create it + lock = Lock.objects.get(name=name) + if datetime.datetime.now() > lock.creation_datetime + datetime.timedelta(seconds=lock.expiration): + release_lock(self) + lock.save() + else: + raise LockError('Unable to acquire lock') + else: + transaction.commit() + + @transaction.commit_manually + def release_lock(self, name): + lock = Lock.objects.get(name=name) + lock.delete() + transaction.commit() + +class Lock(models.Model): + creation_datetime = models.DateTimeField(verbose_name=_(u'creation datetime')) + expiration_time = models.IntegerField(default=3600, verbose_name=_(u'expiration time')) + 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') diff --git a/apps/lock_manager/tests.py b/apps/lock_manager/tests.py new file mode 100644 index 0000000000..501deb776c --- /dev/null +++ b/apps/lock_manager/tests.py @@ -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) diff --git a/apps/lock_manager/views.py b/apps/lock_manager/views.py new file mode 100644 index 0000000000..60f00ef0ef --- /dev/null +++ b/apps/lock_manager/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/settings.py b/settings.py index 32867a3281..baf47dd19a 100644 --- a/settings.py +++ b/settings.py @@ -129,6 +129,7 @@ INSTALLED_APPS = ( 'project_tools', 'smart_settings', 'navigation', + 'lock_manager', 'web_theme', 'common', 'metadata',