victorzhuk/skills

z-go-context

Idiomatic context.Context usage in Go — propagation, cancellation, timeouts, deadlines, WithoutCancel, request-scoped values.

ソースを見る

使い方

  1. インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
  2. 必要なツール、認証情報、対応環境を原文で確認します。
  3. 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/victorzhuk/skills --skill z-go-context

開始前の確認

  • 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
  • スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

context.Context

Quick reference

SituationUse
Entry point (main, init, test body)context.Background()
Function needs ctx but caller doesn't supply one yetcontext.TODO()
HTTP handlerr.Context()
Manual cancellationcontext.WithCancel(parent)
Relative timeoutcontext.WithTimeout(parent, d)
Absolute deadlinecontext.WithDeadline(parent, t)
Background work must outlive request (Go 1.21+)context.WithoutCancel(ctx)

\* context.AfterFunc(ctx, fn) (Go 1.21+) runs fn in its own goroutine when ctx is done — an alternative to WithoutCancel + an explicit select for pure cleanup. Zero use in practice so far; reach for it only if the select pattern below doesn't fit.

Core rules

  • ctx is always the first parameter, always named ctx context.Context.
  • Never store context in a struct — pass it through function parameters.
  • Never pass nil — use context.TODO() if you don't have one yet.
  • Never create context.Background() mid-request — propagate the caller's context.
  • Always defer cancel() immediately after WithCancel/WithTimeout/WithDeadline.
  • Context value keys must be unexported types; bare strings collide across packages.

Propagation

Break the chain and cancellation stops propagating:

go
// bad — new root context, client disconnect ignored
func (s *OrderService) Create(ctx context.Context, o Order) error {
    return s.db.ExecContext(context.Background(), query, o.ID)
}

// good
func (s *OrderService) Create(ctx context.Context, o Order) error {
    return s.db.ExecContext(ctx, query, o.ID)
}

Always use context-aware variants: QueryContext, ExecContext, NewRequestWithContext.

Cancellation

WithCancel lets a parent scope request shutdown of cooperating downstream work. Cancellation does not wait for workers or interrupt code that ignores it; join workers before releasing resources they use. Call cancel() as soon as the reason is gone — the defer handles the normal path; call it explicitly on error to signal early:

go
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if err := doWork(ctx); err != nil {
    cancel() // signal any concurrent workers
    return fmt.Errorf("run: %w", err)
}

For fan-out patterns see [[z-go-concurrency]].

Timeouts and deadlines

Always defer cancel() — discarding the cancel return leaks the timer resource.

go
// relative — most common
func (s *UserService) Get(ctx context.Context, id string) (*User, error) {
    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
    defer cancel()
    return s.repo.FindByID(ctx, id)
}

// absolute — use for SLA-bound batch work
func (s *BatchService) Run(ctx context.Context, b Batch) error {
    ctx, cancel := context.WithDeadline(ctx, b.SLADeadline)
    defer cancel()
    // ...
}

Nested timeouts: the shorter deadline always wins. A 10s child of a 2s parent expires at 2s.

Listening for cancellation

go
func poll(ctx context.Context, interval time.Duration) error {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()
    for {
        select {
        case <-ctx.Done():
            return ctx.Err()
        case <-ticker.C:
            if err := doWork(ctx); err != nil {
                return fmt.Errorf("poll: %w", err)
            }
        }
    }
}

For CPU-bound loops, check ctx.Err() != nil periodically instead of select.

WithoutCancel (Go 1.21+)

Preserves context values but removes cancellation and deadline; Done() is nil. Use only when work deliberately outlives the request. Give it its own bound with context.WithTimeout(context.WithoutCancel(ctx), limit), and arrange application-owned shutdown and joining through [[z-go-concurrency]]. A timeout alone does not make ignored cancellation safe or guarantee delivery of audit records. For work that must survive process exit, use durable delivery.

context.Background() would drop request values. Keeping ctx would retain request cancellation. Neither choice replaces an explicit worker lifetime. See context.WithoutCancel and CancelFunc.

Context values

go
type contextKey string

const (
    traceIDKey   contextKey = "trace_id"
    requestIDKey contextKey = "request_id"
)

func WithTraceID(ctx context.Context, id string) context.Context {
    return context.WithValue(ctx, traceIDKey, id)
}

func TraceIDFromContext(ctx context.Context) (string, bool) {
    v, ok := ctx.Value(traceIDKey).(string)
    return v, ok
}

Bare string keys (context.WithValue(ctx, "trace_id", ...)) collide across packages — never use them.

Context values are for cross-cutting, request-scoped metadata: trace/request IDs, authenticated user or tenant, and loggers enriched with trace fields. Everything else — DB connections, feature flags, business-logic parameters — belongs in constructors or function arguments.

HTTP handlers

Use r.Context() — never context.Background(). After a service call fails, check ctx.Err() != nil before writing an error response (client may already be gone). Middleware enriches context via r.WithContext(ctx) before the handler runs.

Verify

sh
go vet ./...
staticcheck ./...   # SA1012 (nil ctx), SA4006 (unused value); go vet checks lostcancel
同じリポジトリから

関連する Skills

すべての Skills
victorzhuk
コミュニティ

z-accessibility

Audit and improve web accessibility following WCAG 2.2 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible".

導入数
1
GitHub Stars
0
更新日
10月22日
victorzhuk
コミュニティ

z-algo-core

DS/algorithm selection judgment for production code, not competitive tricks — hash map for membership/dedup, slice+sort beats a tree until proven, heap for top-k, two-pointer/sliding-window for scans, BFS/DFS/topo-sort for dependency shapes. Triggers on Big-O, hash map vs tree. Does not cover profiling/tuning; see [[z-go-performance]].

導入数
1
GitHub Stars
0
更新日
10月22日
victorzhuk
コミュニティ

z-bdd

BDD acceptance contracts for humans and agents across UI, API, and CLI products. Use for Gherkin, Given-When-Then, E2E acceptance, or scenario evidence. Define repeatable scenarios with explicit assertions and required outcomes. Test selection belongs to [[z-testing-strategy]]. Go harness wiring belongs to [[z-go-bdd]].

導入数
1
GitHub Stars
0
更新日
10月22日
victorzhuk
コミュニティ

z-codegraph

Use an existing CodeGraph integration for call graphs, impact analysis, affected tests, or route discovery. Discover installed tools and index freshness; follow host LSP precedence and verify current source. Do not initialize indexes without user authorization.

導入数
1
GitHub Stars
0
更新日
10月22日