Knowing what a result backend gives you, and what it costs, prevents both blocked web requests and a Redis full of unused results.
delay() returns an AsyncResult that holds the task id. With a result backend configured, you can ask about the task later, even from another process, with AsyncResult(task_id, app=app).
r.state:PENDING,STARTED(only iftask_track_started=True),RETRY,SUCCESS,FAILUREorREVOKED.r.ready(),r.successful(),r.failed().r.get(timeout=10)waits for the value and re-raises the task's exception if it failed;propagate=Falsereturns the exception instead.r.resultholds the return value or exception without waiting.
A subtle point: PENDING also means "unknown". Celery can't tell a queued task from a nonexistent id, so a typo in an id looks like a task waiting forever.
Avoid calling get() inside a web request (you've just moved the slow work back into the request) and never inside another task, where it can deadlock the worker pool; Celery raises an error by default when you try. Use canvas workflows to chain work instead, and have the client poll or receive a notification.
Results cost storage and network. If nobody reads a task's return value, set ignore_result=True on the task (or task_ignore_result=True globally), and set result_expires so old results are cleaned up (default one day).
Example
from celery import Celery
from celery.result import AsyncResult
app = Celery("tasks", broker="redis://localhost:6379/0",
backend="redis://localhost:6379/1")
@app.task
def add(x, y):
return x + y
@app.task(ignore_result=True)
def log_visit(path):
print("visit", path)
r = add.delay(2, 3)
print(r.state) # PENDING (until a worker picks it up)
print(r.get(timeout=10)) # 5
print(r.state, r.successful()) # SUCCESS True
same = AsyncResult(r.id, app=app) # e.g. from an HTTP polling endpoint
print(same.result) # 5Remember
- AsyncResult(id) lets any process check state and value
- get() blocks and re-raises the task's exception
- PENDING also means 'unknown id'
- ignore_result=True for fire-and-forget tasks; set result_expires
Watch out for
- Calling result.get() inside another task.
- Storing results for millions of tasks nobody reads.