Files
bible/rules/patterns/go-background-tasks/contract.md
2026-03-01 17:16:50 +03:00

76 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (13 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 // 0100
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: 13 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