Add Redis based distributed lock backend
- RedisLock backend requires one argument: "redis_url". Example: redis://127.0.0.1:6379/0 - Add the setting LOCK_MANAGER_BACKEND_ARGUMENTS. Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -169,6 +169,9 @@
|
||||
- Add document type change API endpoint.
|
||||
- Change OCR API submit URL from documents/{pk}/submit
|
||||
to documents/{pk}/ocr/submit.
|
||||
- Add Redis based distributed lock backend. Requires one
|
||||
argument: "redis_url". Example: redis://127.0.0.1:6379/0
|
||||
- Add the setting LOCK_MANAGER_BACKEND_ARGUMENTS.
|
||||
|
||||
3.3.11 (2019-XX-XX)
|
||||
===================
|
||||
|
||||
43
mayan/apps/lock_manager/backends/redis_lock.py
Normal file
43
mayan/apps/lock_manager/backends/redis_lock.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import redis
|
||||
|
||||
from ..exceptions import LockError
|
||||
from ..settings import setting_backend_arguments
|
||||
|
||||
from .base import LockingBackend
|
||||
|
||||
|
||||
class RedisLock(LockingBackend):
|
||||
@classmethod
|
||||
def acquire_lock(cls, name, timeout=None):
|
||||
super(RedisLock, cls).acquire_lock(name=name, timeout=timeout)
|
||||
return RedisLock(name=name, timeout=timeout)
|
||||
|
||||
@classmethod
|
||||
def get_redis_connection(cls):
|
||||
redis_url = setting_backend_arguments.value.get('redis_url', None)
|
||||
server = redis.from_url(url=redis_url)
|
||||
server.client_id()
|
||||
return server
|
||||
|
||||
@classmethod
|
||||
def purge_locks(cls):
|
||||
super(RedisLock, cls).purge_locks()
|
||||
|
||||
def __init__(self, name, timeout):
|
||||
self.name = name
|
||||
redis_lock_instance = self.get_redis_connection().lock(
|
||||
name=name, timeout=timeout, sleep=0.1, blocking_timeout=0.1
|
||||
)
|
||||
if redis_lock_instance.acquire():
|
||||
self.redis_lock_instance = redis_lock_instance
|
||||
else:
|
||||
raise LockError
|
||||
|
||||
def release(self):
|
||||
super(RedisLock, self).release()
|
||||
try:
|
||||
self.redis_lock_instance.release()
|
||||
except redis.exceptions.LockNotOwnedError:
|
||||
return
|
||||
@@ -15,6 +15,10 @@ setting_backend = namespace.add_setting(
|
||||
'resource locks.'
|
||||
)
|
||||
)
|
||||
setting_backend_arguments = namespace.add_setting(
|
||||
global_name='LOCK_MANAGER_BACKEND_ARGUMENTS',
|
||||
default={}, help_text=_('Arguments to pass to the LOCK_MANAGER_BACKEND.')
|
||||
)
|
||||
|
||||
setting_default_lock_timeout = namespace.add_setting(
|
||||
default=DEFAULT_LOCK_TIMEOUT_VALUE,
|
||||
|
||||
@@ -2,18 +2,21 @@ from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
|
||||
from django.test import TestCase
|
||||
from django.test import override_settings
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
from mayan.apps.common.tests.base import BaseTestCase
|
||||
|
||||
from ..exceptions import LockError
|
||||
|
||||
TEST_LOCK_1 = 'test lock 1'
|
||||
|
||||
|
||||
class FileLockTestCase(TestCase):
|
||||
class FileLockTestCase(BaseTestCase):
|
||||
backend_string = 'mayan.apps.lock_manager.backends.file_lock.FileLock'
|
||||
|
||||
def setUp(self):
|
||||
super(FileLockTestCase, self).setUp()
|
||||
self.locking_backend = import_string(self.backend_string)
|
||||
|
||||
def test_exclusive(self):
|
||||
@@ -72,3 +75,10 @@ class FileLockTestCase(TestCase):
|
||||
|
||||
class ModelLockTestCase(FileLockTestCase):
|
||||
backend_string = 'mayan.apps.lock_manager.backends.model_lock.ModelLock'
|
||||
|
||||
|
||||
@override_settings(
|
||||
LOCK_MANAGER_BACKEND_ARGUMENTS={'redis_url': 'redis://127.0.0.1:6379/0'}
|
||||
)
|
||||
class RedisLockTestCase(FileLockTestCase):
|
||||
backend_string = 'mayan.apps.lock_manager.backends.redis_lock.RedisLock'
|
||||
|
||||
Reference in New Issue
Block a user