1
0
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:
Kenny Lee Sin Cheong
2021-04-14 14:44:33 -04:00
committed by GitHub
parent 778afaf36b
commit c12654bf46
7 changed files with 25 additions and 14 deletions

View File

@ -3,8 +3,6 @@ import logging
from redis import RedisError
from redlock import RedLockFactory, RedLockError
from app import app
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,
# 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
@ -28,21 +39,15 @@ class GlobalLock(object):
lock_factory = None
def __new__(cls, *args, **kwargs):
@classmethod
def configure(cls, config):
if cls.lock_factory is None:
_redis_info = dict(app.config["USER_EVENTS_REDIS"])
_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)
cls.lock_factory = _redlock_factory(config)
def __init__(self, name, lock_ttl=600):
if GlobalLock.lock_factory is None:
raise LockNotAcquiredException("GlobalLock not configured")
self._lock_name = name
self._lock_ttl = lock_ttl
self._redlock = None

View File

@ -86,5 +86,6 @@ def create_gunicorn_worker():
if __name__ == "__main__":
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
GlobalLock.configure(app.config)
worker = BlobUploadCleanupWorker()
worker.start()

View File

@ -91,5 +91,6 @@ if __name__ == "__main__":
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
worker = GarbageCollectionWorker()
worker.start()

View File

@ -87,6 +87,7 @@ def main():
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
worker = GlobalPrometheusStatsWorker()
worker.start()

View File

@ -153,6 +153,7 @@ def main():
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
worker = LogRotateWorker()
worker.start()

View File

@ -69,6 +69,7 @@ if __name__ == "__main__":
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
logger.debug("Starting namespace GC worker")
worker = NamespaceGCWorker(
namespace_gc_queue,

View File

@ -78,6 +78,7 @@ if __name__ == "__main__":
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
logger.debug("Starting repository GC worker")
worker = RepositoryGCWorker(
repository_gc_queue,