76 lines
2.4 KiB
Markdown
76 lines
2.4 KiB
Markdown
# Contract: Background Tasks (Go Web Applications)
|
||
|
||
Version: 1.0
|
||
|
||
## Core Rule
|
||
|
||
All long-running operations (> ~300ms or uncertain duration) must run as background tasks.
|
||
Never block an HTTP handler waiting for a slow operation to complete.
|
||
|
||
## Standard Flow
|
||
|
||
```
|
||
POST /api/something → creates task → returns {task_id}
|
||
GET /api/tasks/:id → client polls → returns status + progress
|
||
UI shows spinner → on success: toast + refresh
|
||
```
|
||
|
||
The client polls `/api/tasks/:id` on a fixed interval (1–3 s) until status is terminal.
|
||
|
||
## Task Status Values
|
||
|
||
| Status | Meaning |
|
||
|-------------|---------|
|
||
| `queued` | Created, not yet started |
|
||
| `running` | In progress |
|
||
| `success` | Completed successfully |
|
||
| `failed` | Completed with error |
|
||
| `canceled` | Explicitly canceled by user |
|
||
|
||
## Task Struct (canonical fields)
|
||
|
||
```go
|
||
type Task struct {
|
||
ID string
|
||
Type string // e.g. "recalculate", "import", "export"
|
||
Status string
|
||
Progress int // 0–100
|
||
Message string // human-readable current step
|
||
Result any // populated on success (row count, file URL, etc.)
|
||
Error string // populated on failure
|
||
CreatedAt time.Time
|
||
UpdatedAt time.Time
|
||
}
|
||
```
|
||
|
||
## Rules
|
||
|
||
- Do NOT use SSE (Server-Sent Events) for task progress. Use polling.
|
||
SSE requires persistent connections and complicates load balancers and proxies.
|
||
- One task per operation. Do not batch unrelated operations into a single task.
|
||
- Tasks must be stored in memory (or DB for persistence) with a TTL — clean up after completion.
|
||
- Handler that creates the task returns `202 Accepted` with `{"task_id": "..."}`.
|
||
- Log task start, finish, and error server-side (see go-logging contract).
|
||
|
||
## UI Contract
|
||
|
||
- Show a spinner/progress bar while `status == "running"`.
|
||
- On `success`: show toast notification, refresh affected data.
|
||
- On `failed`: show error message from `task.Error`.
|
||
- Poll interval: 1–3 seconds. Stop polling on terminal status.
|
||
- Do not disable the whole page during task execution — allow user to navigate away.
|
||
|
||
## What Qualifies as a Background Task
|
||
|
||
- CSV/file export with > ~500 rows
|
||
- Bulk recalculation or recompute operations
|
||
- External API calls (sync, collect, import from remote)
|
||
- Any import/ingest that touches multiple DB tables
|
||
- Database repair or cleanup operations
|
||
|
||
## What Does NOT Need a Background Task
|
||
|
||
- Simple CRUD operations (create/update/delete single record)
|
||
- Filtered list queries
|
||
- Single-record exports
|