Separate acknowledgement from execution
When work is accepted, show a job ID and a route back to its status. “Queued” means the service accepted the job, not that execution began. “Running” means the service reports active work. Use a percentage only when the backend measures a meaningful numerator and denominator; otherwise use an indeterminate progress treatment and explain the current phase.
The W3C's progress technique
shows that changing aria-valuenow alone may not announce updates. It pairs the
progress indicator with a live status message. Updates should be useful rather
than chatty: announce important phase changes and terminal results.
“Cancel requested” is its own state
Cancellation is often a request, not an immediate fact. After the operator asks to cancel, say “Cancellation requested; work may continue until the service confirms.” Prevent repeated cancellation requests but keep the job ID visible.
MDN documents that AbortController
can abort browser-side requests, response consumption, and streams. That does
not establish that a remote background job stopped. Show “Cancelled” only after
the job service acknowledges its terminal state, and disclose any partial
effects that cannot be rolled back.
Preserve unknown as an honest outcome
If status polling fails, keep the last confirmed phase and timestamp but label the current state unknown. Do not convert a lost status response into “Failed” and do not assume a completed result. The job ID is the reconciliation handle.
| State | Minimum visible content |
|---|---|
| Queued | Job ID, accepted time, next status check |
| Running | Current phase or measured progress |
| Cancel requested | Request time and pending acknowledgement |
| Completed | Completion time and result link |
| Failed | Specific failure and safe retry policy |
| Cancelled | Server acknowledgement and partial effects |
| Unknown | Last confirmed state and reconciliation action |
Acceptance checks
- The job remains identifiable after navigation or reload.
- Queued and running are not compressed into one spinner state.
- Percent complete appears only when meaningfully measured.
- Cancel requested remains pending until server acknowledgement.
- Closing the page or aborting fetch never claims the job stopped.
- Terminal results remain retrievable.
- Unknown is distinct from failed and completed.
- Important phase and terminal changes are programmatic status messages.
These checks do not implement a queue, idempotency, cancellation, rollback, or durable result storage. Those guarantees belong to the job service.