Search code examples
rabbitmqcelery

Celery task with a long ETA and RabbitMQ


RabbitMQ may enforce ack timeouts for consumers: https://www.rabbitmq.com/consumers.html#acknowledgement-modes By default if a task has not been acked within 15 min entire node will go down with a PreconditionFailed error. I need to schedule a celery task (using RabbitMQ as a broker) with an ETA quite far in the future (1-3 h) and as of now (with celery 4 and rabbitmq 3.8) when I try that... I get PreconditionFailed after the consumer ack timeout configured for my RMQ. I expected that the task would be acknolwedged before its ETA ...

Is there a way to configure an ETA celery task to be acknowledged within the consumer ack timeout?

right now I am increasing the consumer_timeout to above my ETA time delta, but there must be a better solution ...


Solution

  • I think adjusting the consumer_timeout is your only option in Celery 5. Note that this is only applicable for RabbitMQ 3.8.15 and newer.

    Another possible solution is to have the workers ack the message immediately upon receipt. Do this only if you don't need to guarantee task completion. For example, if the worker crashes before doing the task, Celery will not know that it wasn't completed.

    In RabbitMQ, the best options for delayed tasks are the delayed-message-exchange or dead lettering. Celery cannot use either option. In Celery, messages are published to the message broker where they are sent to consumers as soon as possible. The delay is enforced in the worker, not at the broker.