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

2.4 KiB
Raw Blame History

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)

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