Update lock managet app
Add keyword arguments. Sort imports. Move settings and test literals to their own module. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
@@ -23,7 +23,9 @@ lock = threading.Lock()
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
lock_file = os.path.join(
|
lock_file = os.path.join(
|
||||||
setting_temporary_directory.value, hashlib.sha256(force_bytes(settings.SECRET_KEY)).hexdigest()
|
setting_temporary_directory.value, hashlib.sha256(
|
||||||
|
force_bytes(settings.SECRET_KEY)
|
||||||
|
).hexdigest()
|
||||||
)
|
)
|
||||||
open(lock_file, 'a').close()
|
open(lock_file, 'a').close()
|
||||||
logger.debug('lock_file: %s', lock_file)
|
logger.debug('lock_file: %s', lock_file)
|
||||||
@@ -76,7 +78,7 @@ class FileLock(LockingBackend):
|
|||||||
data = file_object.read()
|
data = file_object.read()
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
file_locks = json.loads(data)
|
file_locks = json.loads(s=data)
|
||||||
else:
|
else:
|
||||||
file_locks = {}
|
file_locks = {}
|
||||||
|
|
||||||
@@ -103,7 +105,7 @@ class FileLock(LockingBackend):
|
|||||||
with open(self.__class__.lock_file, 'r+') as file_object:
|
with open(self.__class__.lock_file, 'r+') as file_object:
|
||||||
locks.lock(f=file_object, flags=locks.LOCK_EX)
|
locks.lock(f=file_object, flags=locks.LOCK_EX)
|
||||||
try:
|
try:
|
||||||
file_locks = json.loads(file_object.read())
|
file_locks = json.loads(s=file_object.read())
|
||||||
except EOFError:
|
except EOFError:
|
||||||
file_locks = {}
|
file_locks = {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import time
|
|
||||||
import random
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
from .exceptions import LockError
|
from .exceptions import LockError
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
||||||
class LockError(Exception):
|
class LockError(Exception):
|
||||||
pass
|
"""Raised when trying to acquire an existing lock"""
|
||||||
|
|||||||
4
mayan/apps/lock_manager/literals.py
Normal file
4
mayan/apps/lock_manager/literals.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
DEFAULT_BACKEND = 'mayan.apps.lock_manager.backends.file_lock.FileLock'
|
||||||
|
DEFAULT_LOCK_TIMEOUT_VALUE = 30
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class Lock(models.Model):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
lock = Lock.objects.get(
|
lock = Lock.objects.get(
|
||||||
name=self.name, creation_datetime=self.creation_datetime
|
creation_datetime=self.creation_datetime, name=self.name
|
||||||
)
|
)
|
||||||
except Lock.DoesNotExist:
|
except Lock.DoesNotExist:
|
||||||
# Our lock has expired and was reassigned
|
# Our lock has expired and was reassigned
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.utils.module_loading import import_string
|
|||||||
|
|
||||||
from .settings import setting_backend
|
from .settings import setting_backend
|
||||||
|
|
||||||
locking_backend = import_string(setting_backend.value)
|
locking_backend = import_string(dotted_path=setting_backend.value)
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from mayan.apps.smart_settings import Namespace
|
from mayan.apps.smart_settings import Namespace
|
||||||
|
|
||||||
DEFAULT_BACKEND = 'mayan.apps.lock_manager.backends.file_lock.FileLock'
|
from .literals import DEFAULT_BACKEND, DEFAULT_LOCK_TIMEOUT_VALUE
|
||||||
DEFAULT_LOCK_TIMEOUT_VALUE = 30
|
|
||||||
|
|
||||||
namespace = Namespace(name='lock_manager', label=_('Lock manager'))
|
namespace = Namespace(label=_('Lock manager'), name='lock_manager')
|
||||||
|
|
||||||
setting_backend = namespace.add_setting(
|
setting_backend = namespace.add_setting(
|
||||||
default=DEFAULT_BACKEND,
|
default=DEFAULT_BACKEND,
|
||||||
|
|||||||
3
mayan/apps/lock_manager/tests/literals.py
Normal file
3
mayan/apps/lock_manager/tests/literals.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
TEST_LOCK_NAME = 'test lock name'
|
||||||
@@ -7,51 +7,53 @@ from django.utils.module_loading import import_string
|
|||||||
|
|
||||||
from ..exceptions import LockError
|
from ..exceptions import LockError
|
||||||
|
|
||||||
TEST_LOCK_1 = 'test lock 1'
|
from .literals import TEST_LOCK_NAME
|
||||||
|
|
||||||
|
|
||||||
class FileLockTestCase(TestCase):
|
class FileLockTestCase(TestCase):
|
||||||
backend_string = 'mayan.apps.lock_manager.backends.file_lock.FileLock'
|
backend_string = 'mayan.apps.lock_manager.backends.file_lock.FileLock'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.locking_backend = import_string(self.backend_string)
|
self.locking_backend = import_string(dotted_path=self.backend_string)
|
||||||
|
|
||||||
def test_exclusive(self):
|
def test_exclusive(self):
|
||||||
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
with self.assertRaises(LockError):
|
with self.assertRaises(LockError):
|
||||||
self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
lock_1.release()
|
lock_1.release()
|
||||||
|
|
||||||
def test_release(self):
|
def test_release(self):
|
||||||
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
lock_1.release()
|
lock_1.release()
|
||||||
lock_2 = self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
lock_2 = self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
lock_2.release()
|
lock_2.release()
|
||||||
|
|
||||||
def test_timeout_expired(self):
|
def test_timeout_expired(self):
|
||||||
self.locking_backend.acquire_lock(name=TEST_LOCK_1, timeout=1)
|
self.locking_backend.acquire_lock(name=TEST_LOCK_NAME, timeout=1)
|
||||||
|
|
||||||
# lock_1 not release and not expired, should raise LockError
|
# lock_1 not release and not expired, should raise LockError
|
||||||
with self.assertRaises(LockError):
|
with self.assertRaises(LockError):
|
||||||
self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
|
|
||||||
time.sleep(1.01)
|
time.sleep(1.01)
|
||||||
# lock_1 not release but has expired, should not raise LockError
|
# lock_1 not release but has expired, should not raise LockError
|
||||||
lock_2 = self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
lock_2 = self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
lock_2.release()
|
lock_2.release()
|
||||||
|
|
||||||
def test_double_release(self):
|
def test_double_release(self):
|
||||||
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_1)
|
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_NAME)
|
||||||
lock_1.release()
|
lock_1.release()
|
||||||
|
|
||||||
def test_release_expired(self):
|
def test_release_expired(self):
|
||||||
lock_1 = self.locking_backend.acquire_lock(name=TEST_LOCK_1, timeout=1)
|
lock_1 = self.locking_backend.acquire_lock(
|
||||||
|
name=TEST_LOCK_NAME, timeout=1
|
||||||
|
)
|
||||||
time.sleep(1.01)
|
time.sleep(1.01)
|
||||||
lock_1.release()
|
lock_1.release()
|
||||||
# No exception is raised even though the lock has expired.
|
# No exception is raised even though the lock has expired.
|
||||||
@@ -60,11 +62,13 @@ class FileLockTestCase(TestCase):
|
|||||||
# would be successfull, even after an extended lapse of time
|
# would be successfull, even after an extended lapse of time
|
||||||
|
|
||||||
def test_release_expired_reaquired(self):
|
def test_release_expired_reaquired(self):
|
||||||
self.locking_backend.acquire_lock(name=TEST_LOCK_1, timeout=1)
|
self.locking_backend.acquire_lock(name=TEST_LOCK_NAME, timeout=1)
|
||||||
time.sleep(1.01)
|
time.sleep(1.01)
|
||||||
# TEST_LOCK_1 is expired so trying to acquire it should not return an
|
# TEST_LOCK_NAME is expired so trying to acquire it should not return
|
||||||
# error.
|
# an error.
|
||||||
lock_2 = self.locking_backend.acquire_lock(name=TEST_LOCK_1, timeout=1)
|
lock_2 = self.locking_backend.acquire_lock(
|
||||||
|
name=TEST_LOCK_NAME, timeout=1
|
||||||
|
)
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
lock_2.release()
|
lock_2.release()
|
||||||
|
|||||||
Reference in New Issue
Block a user