0

Is there a way to modify the retry delay for celery tasks at runtime? Or is there a global config value that can be changed to override the 180s default value?

I have set up tasks with exponential back-off (as described here: Retry Celery tasks with exponential back off) but I want to override this value when integration testing.

The reason is that I often end up triggering the 180s default value if exceptions are raised within an exception handler, which seems to bypass and ignore the countdown argument.

class BaseTask(celery.Task):
    def on_retry(self, exc, task_id, args, kwargs, einfo):
        """Log the exceptions at retry."""
        logger.exception(exc)
        logger.warning('Retry: {}.'.format(self.request))
        super().on_retry(exc, task_id, args, kwargs, einfo)

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        """Log the exceptions on failure."""
        logger.exception(exc)
        logger.error('Failure: {}.'.format(self.request))
        super().on_failure(exc, task_id, args, kwargs, einfo)

    @property
    def backoff_countdown(self):
        return int(random.uniform(2, 4) ** self.request.retries)

@celery.task(bind=True, base=BaseTask)
def process(self, data):
    try:
        return some_task(data)
    except Exception as exc:
        raise self.retry(exc=exc, coundown=self.backoff_countdown)

Regardless of what I set for self.backoff_countdown (even just returning 1) I end up with tasks being retried in 180s, which makes it really hard to run integration tests with reasonable timeouts.

1 Answer 1

1

Refer to document http://docs.celeryproject.org/en/latest/userguide/tasks.html#using-a-custom-retry-delay, can set default_retry_delay or set the countdown value.

@celery.task(bind=True, default_retry_delay=30 * 60) # retry in 30 minutes.
def process(self, data):
    try:
        return some_task(data)
    except Exception as exc:
        # Retry in 5 minutes
        raise self.retry(exc=exc, countdown=5 * 60)
Sign up to request clarification or add additional context in comments.

5 Comments

Yes, I know of that setting but it's not something I can change at runtime - at least not that I can see. Maybe I'm phrasing this badly. I'm ok with the 3min normal retry delay and I don't want to change that in the source. However, I do want to override that value when I run this same source in a docker image by some configuration setting that I can inject or by some instrumentation that I add to my tests.
How about override the retry method of Task object?
This code is running in a docker container. The best I can do is inject config files or set env variables. I guess I could try to inject a value for @celery.task(... default_retry_delay=...) via an env variable but that seems awfully convoluted and is not something I'd like to ship.
From your code, i don't see your method is override the default_retry_delay value, you can try to override the retry method of Task object with your countdown parameter.
I think a better description of my problem would be: Given the tasks are defined as shown and assuming that I cannot change them, how could I adjust default_retry_delay from the 'outside' to achieve the same effect as via the @celery.task decorator.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.