12

I have a task:

 @celery.task(name='request_task',default_retry_delay=2,acks_late=True) def request_task(data): try: if some_condition: request_task.retry() except Exception as e: request_task.retry() 

I use celery with mongodb broker and mongodb results backend enabled.

When task's retry() method is called, neither from conditional statement nor after catching exception, the task is not retried.

in the worker's terminal I get message like this:

[2012-08-10 19:21:54,909: INFO/MainProcess] Task request_task[badb3131-8964-41b5-90a7-245a8131e68d] retry: Task can be retried

What can be wrong?

UPDATE: Finally, I did not solve this question and had to use while loop inside the task, so my tasks never get retried.

3
  • Which celery version you are using ? Commented Jan 3, 2014 at 9:05
  • @MauroRocco I used celery 3.0.4 at time question was asked. I had some features working with bugs in versions 3.0.4 and 3.0.5 but later versions worked pretty well. Commented Jan 4, 2014 at 11:07
  • Glad to hear that.If you can answer yourself the question and explain better the resolution. Commented Jan 5, 2014 at 13:21

2 Answers 2

7

I know this answer is too late, but the log message you're seeing means that you're calling the task directly request_task() and not queuing it so it's not running on a worker, so doing this will raise the exception if there is any, or a Retry exception, this is the code from the Task.retry method if you want to look at:

# Not in worker or emulated by (apply/always_eager), # so just raise the original exception. if request.called_directly: # raises orig stack if PyErr_Occurred, # and augments with exc' if that argument is defined. raise_with_context(exc or Retry('Task can be retried', None)) 

Using task.retry() does not retry the task on the same worker, it sends a new message using task.apply_async() so it might be retried using another worker, this is what you should take into account when handling retries, you can access the retries count using task.request.retries and you can also set max_retries option on the task decorator.

By the way using bind=True on the task decorator makes the task instance available as the first argument:

@app.task(bind=True, name='request_task', max_retries=3) def request_task(self, data): # Task retries count self.request.retries try: # Your code here except SomeException as exc: # Retry the task # Passing the exc argument will make the task fail # with this exception instead of MaxRetriesExceededError on max retries self.retry(exc=exc) 
Sign up to request clarification or add additional context in comments.

Comments

2

You should read the section on retrying in the Celery docs. http://celery.readthedocs.org/en/latest/userguide/tasks.html#retrying

It looks like in order to retry, you must raise a retry exception.

raise request_task.retry() 

That seems to make the retry be handled by the function that decorated your task.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.