Results#

Every enqueue returns a TaskResult linked to its QueueService:

result = await queue_service.enqueue(render_report, "report-123")
await result.wait(timeout=30)

if result.status == "completed":
    report_path = result.result
elif result.status == "failed":
    error = result.error

wait() checks the task until its state is completed, failed, cancelled, or expired. It raises TimeoutError when its own waiting timeout expires. That local timeout does not stop or expire the queued task.

Refresh cached state#

TaskResult.status, result, error, and record are cached. Call:

await result.refresh()

before reading a later state. Persistent backends return a new record object instead of changing the original object in place. Call refresh() so the same code works with every backend.

Lifecycle events are notifications, not replacement result objects. The queue stores a completed result before it publishes task.completed (and stores a terminal error before the corresponding final failure event), but an existing TaskResult remains a cache. Refresh it after receiving a terminal event before reading status, result, or error.

Result ownership#

The queue backend owns the source record. A TaskResult is a handle to that record and needs its queue service for refresh() or wait(). Cleanup may eventually remove finished records. Copy business results into app-owned storage when you must keep them indefinitely.