- Generic task polling — for status-change tasks that return a task id.
- Resource-status polling — for resources that carry a
statusfield (packages, taste-cluster runs).
Pattern 1 — Generic task polling
Some endpoints kick off a background task and return a task id:Helper
PUT /events/{eid}/client_campaign_status?...— has a task-state poll atGET /events/{eid}/client_campaign_status/task.
/tasks/{id}.
Pattern 2 — Resource-status polling
Some resources carry their ownstatus field that transitions over time.
Poll the resource itself:
- Package Builder —
GET /package_builder/packages/{id}polled every 5s untilstatus === "DONE" | "FAILED" | "EXPIRED". - Taste cluster runs / ITC — typically caller-driven (kick the DAG, poll the per-event endpoint).
Pattern in the Package Builder
AbortSignal tied to component lifetime. The reference
webapp doesn’t do this and leaks polling loops on unmount.
Don’t poll harder than necessary
Server budgets assume gentle polling:| Resource | Reference webapp interval |
|---|---|
| Package status | 5s |
| Notification stats badge | 10s |
| Messages unread badge | 15 min |
| Task state | 2s (with backoff) |
Combining with React Query
If you’re using@tanstack/react-query, leverage refetchInterval:
Caveats
No webhooks today
No webhooks today
There is no callback URL you can register. Plan for polling on your
side. (If your integration needs near-real-time push, talk to your
account contact — bespoke webhook arrangements are possible.)
Polling without unmount cancellation leaks
Polling without unmount cancellation leaks
Always tie your poll to an
AbortController (or component-mounted
flag, or React Query). The reference webapp’s package poll doesn’t do
this — don’t copy that bug.Backoff > constant interval
Backoff > constant interval
A task that’s been running for 30 minutes is probably stuck; bombarding
its endpoint at 200ms doesn’t help. Use linear or exponential backoff
capped at 10s.
Tasks that "complete" without a result
Tasks that "complete" without a result
Some task endpoints return
state: "completed" with an empty result.
That’s still success — the side effect happened on the server.