Leon4gr45's picture
Deploy complete BrainAPI source ea2acb63d782
89e57b7 verified
Raw History Blame Contribute Delete
2.02 kB
"""Account for every accepted Celery delivery, including retries and chains."""
import uuid
from celery import Task, current_task
from . import maintenance as gate
from .state import enabled
from .git import BackupError
HEADER = 'brainapi-backup-work'
class ContentTask(Task):
abstract = True
def apply_async(self, args=None, kwargs=None, **options):
if not enabled():
return super().apply_async(args=args, kwargs=kwargs, **options)
parent = getattr(getattr(current_task, 'request', None), 'headers', None) or {}
work_id = uuid.uuid4().hex
parent_id = getattr(getattr(current_task, 'request', None), 'backup_execution', None) or parent.get(HEADER)
gate.register_task(work_id, parent_id)
headers = dict(options.pop('headers', None) or {})
headers[HEADER] = work_id
# An ambiguous publication failure deliberately stays pending: fail closed
# rather than claim a durable barrier while a message might be in flight.
return super().apply_async(args=args, kwargs=kwargs, headers=headers, **options)
def __call__(self, *args, **kwargs):
if not enabled():
return super().__call__(*args, **kwargs)
work_id = (self.request.headers or {}).get(HEADER)
self.request.backup_execution = gate.begin_task(work_id)
token = gate._admitted.set(True)
try:
return super().__call__(*args, **kwargs)
finally:
gate._admitted.reset(token)
def after_return(self, status, retval, task_id, args, kwargs, einfo):
gate.finish_task((self.request.headers or {}).get(HEADER), getattr(self.request, 'backup_execution', None))
return super().after_return(status, retval, task_id, args, kwargs, einfo)
def on_retry(self, exc, task_id, args, kwargs, einfo):
gate.finish_task((self.request.headers or {}).get(HEADER), getattr(self.request, 'backup_execution', None))
return super().on_retry(exc, task_id, args, kwargs, einfo)