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:
Roberto Rosario
2019-01-21 02:50:34 -04:00
parent 027a853885
commit 09edab5027
11 changed files with 43 additions and 28 deletions

View File

@@ -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 = {}

View File

@@ -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

View File

@@ -1,2 +1,5 @@
from __future__ import unicode_literals
class LockError(Exception): class LockError(Exception):
pass """Raised when trying to acquire an existing lock"""

View 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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -0,0 +1,3 @@
from __future__ import unicode_literals
TEST_LOCK_NAME = 'test lock name'

View File

@@ -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()