mirror of
https://github.com/quay/quay.git
synced 2025-07-31 18:44:32 +03:00
lock: allows global lock to be used from main app (PROJQUAY-788) (#745)
GlobalLock had a dependency on app, which would cause a circular dependency if imported from the main app. Workaround this by requiring to pass the configuration to the GlobalLock instead (this is done by a classmethod, due to the use of Redlock's factory). This means before the use of GlobalLock, "configure" will need to be called once, per process.
This commit is contained in:
committed by
GitHub
parent
778afaf36b
commit
c12654bf46
@ -3,8 +3,6 @@ import logging
|
|||||||
from redis import RedisError
|
from redis import RedisError
|
||||||
from redlock import RedLockFactory, RedLockError
|
from redlock import RedLockFactory, RedLockError
|
||||||
|
|
||||||
from app import app
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -14,6 +12,19 @@ class LockNotAcquiredException(Exception):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _redlock_factory(config):
|
||||||
|
_redis_info = dict(config["USER_EVENTS_REDIS"])
|
||||||
|
_redis_info.update(
|
||||||
|
{
|
||||||
|
"socket_connect_timeout": 5,
|
||||||
|
"socket_timeout": 5,
|
||||||
|
"single_connection_client": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
lock_factory = RedLockFactory(connection_details=[_redis_info])
|
||||||
|
return lock_factory
|
||||||
|
|
||||||
|
|
||||||
# TODO(kleesc): GlobalLock should either renew the lock until the caller is done,
|
# TODO(kleesc): GlobalLock should either renew the lock until the caller is done,
|
||||||
# or signal that it is no longer valid to the caller. Currently, GlobalLock will
|
# or signal that it is no longer valid to the caller. Currently, GlobalLock will
|
||||||
# just silently expire the redis key, making the lock available again while any
|
# just silently expire the redis key, making the lock available again while any
|
||||||
@ -28,21 +39,15 @@ class GlobalLock(object):
|
|||||||
|
|
||||||
lock_factory = None
|
lock_factory = None
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
@classmethod
|
||||||
|
def configure(cls, config):
|
||||||
if cls.lock_factory is None:
|
if cls.lock_factory is None:
|
||||||
_redis_info = dict(app.config["USER_EVENTS_REDIS"])
|
cls.lock_factory = _redlock_factory(config)
|
||||||
_redis_info.update(
|
|
||||||
{
|
|
||||||
"socket_connect_timeout": 5,
|
|
||||||
"socket_timeout": 5,
|
|
||||||
"single_connection_client": True,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
cls.lock_factory = RedLockFactory(connection_details=[_redis_info])
|
|
||||||
return super(GlobalLock, cls).__new__(cls, *args, **kwargs)
|
|
||||||
|
|
||||||
def __init__(self, name, lock_ttl=600):
|
def __init__(self, name, lock_ttl=600):
|
||||||
|
if GlobalLock.lock_factory is None:
|
||||||
|
raise LockNotAcquiredException("GlobalLock not configured")
|
||||||
|
|
||||||
self._lock_name = name
|
self._lock_name = name
|
||||||
self._lock_ttl = lock_ttl
|
self._lock_ttl = lock_ttl
|
||||||
self._redlock = None
|
self._redlock = None
|
||||||
|
@ -86,5 +86,6 @@ def create_gunicorn_worker():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
worker = BlobUploadCleanupWorker()
|
worker = BlobUploadCleanupWorker()
|
||||||
worker.start()
|
worker.start()
|
||||||
|
@ -91,5 +91,6 @@ if __name__ == "__main__":
|
|||||||
while True:
|
while True:
|
||||||
time.sleep(100000)
|
time.sleep(100000)
|
||||||
|
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
worker = GarbageCollectionWorker()
|
worker = GarbageCollectionWorker()
|
||||||
worker.start()
|
worker.start()
|
||||||
|
@ -87,6 +87,7 @@ def main():
|
|||||||
while True:
|
while True:
|
||||||
time.sleep(100000)
|
time.sleep(100000)
|
||||||
|
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
worker = GlobalPrometheusStatsWorker()
|
worker = GlobalPrometheusStatsWorker()
|
||||||
worker.start()
|
worker.start()
|
||||||
|
|
||||||
|
@ -153,6 +153,7 @@ def main():
|
|||||||
while True:
|
while True:
|
||||||
time.sleep(100000)
|
time.sleep(100000)
|
||||||
|
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
worker = LogRotateWorker()
|
worker = LogRotateWorker()
|
||||||
worker.start()
|
worker.start()
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ if __name__ == "__main__":
|
|||||||
while True:
|
while True:
|
||||||
time.sleep(100000)
|
time.sleep(100000)
|
||||||
|
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
logger.debug("Starting namespace GC worker")
|
logger.debug("Starting namespace GC worker")
|
||||||
worker = NamespaceGCWorker(
|
worker = NamespaceGCWorker(
|
||||||
namespace_gc_queue,
|
namespace_gc_queue,
|
||||||
|
@ -78,6 +78,7 @@ if __name__ == "__main__":
|
|||||||
while True:
|
while True:
|
||||||
time.sleep(100000)
|
time.sleep(100000)
|
||||||
|
|
||||||
|
GlobalLock.configure(app.config)
|
||||||
logger.debug("Starting repository GC worker")
|
logger.debug("Starting repository GC worker")
|
||||||
worker = RepositoryGCWorker(
|
worker = RepositoryGCWorker(
|
||||||
repository_gc_queue,
|
repository_gc_queue,
|
||||||
|
Reference in New Issue
Block a user