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.