两种模式的 Go 架构辅助 —— 设计新 API 或审查现有代码中的隐藏问题。
设计与多媒体
golang-context
试用Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code that merely accepts ctx as first parameter.
它能做什么
Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code that merely accepts ctx as first parameter.
技能文档
Community default. A company skill that explicitly supersedes
samber/cc-skills-golang@golang-contextskill takes precedence.
Go context.Context Best Practices
context.Context is Go's mechanism for propagating cancellation signals, deadlines, and request-scoped values across API boundaries and between goroutines. Think of it as the "session" of a request — it ties together every operation that belongs to the same unit of work.
Best Practices Summary
- The same context MUST be propagated through the entire request lifecycle: HTTP handler → service → DB → external APIs
ctxMUST be the first parameter, namedctx context.Context- NEVER store context in a struct — pass explicitly through function parameters
- NEVER pass
nilcontext — usecontext.TODO()if unsure cancel()MUST be called on all control-flow paths forWithCancel/WithTimeout/WithDeadline, unless ownership of the context and cancel function is explicitly returned or transferredcontext.Background()MUST only be used at the top level (main, init, tests)- Use
context.TODO()as a placeholder when you know a context is needed but don't have one yet - NEVER create a new
context.Background()in the middle of a request path - Context value keys MUST be unexported types to prevent collisions
- Context values MUST only carry request-scoped metadata — NEVER function parameters
- Use
context.WithoutCancel(Go 1.21+) when spawning background work that must outlive the parent request
Creating Contexts
| Situation | Use |
|---|---|
| Entry point (main, init, test) | context.Background() |
| Function needs context but caller doesn't provide one yet | context.TODO() |
| Inside an HTTP handler | r.Context() |
| Need cancellation control | context.WithCancel(parentCtx) |
| Need a deadline/timeout | context.WithTimeout(parentCtx, duration) |
Context Propagation: The Core Principle
The most important rule: propagate the same context through the entire call chain. When you propagate correctly, cancelling the parent context cancels all downstream work automatically.
// ✗ Bad — creates a new context, breaking the chain
func (s *OrderService) Create(ctx context.Context, order Order) error {
return s.db.ExecContext(context.Background(), "INSERT INTO orders ...", order.ID)
}
// ✓ Good — propagates the caller's context
func (s *OrderService) Create(ctx context.Context, order Order) error {
return s.db.ExecContext(ctx, "INSERT INTO orders ...", order.ID)
}
Deep Dives
-
Cancellation, Timeouts & Deadlines — How cancellation propagates:
WithCancelfor manual cancellation,WithTimeoutfor automatic cancellation after a duration,WithDeadlinefor absolute time deadlines. Patterns for listening (<-ctx.Done()) in concurrent code,AfterFunccallbacks, andWithoutCancelfor operations that must outlive their parent request (e.g., audit logs). -
Context Values & Cross-Service Tracing — Safe context value patterns: unexported key types to prevent namespace collisions, when to use context values (request ID, user ID) vs function parameters. Trace context propagation: OpenTelemetry trace headers, correlation IDs for log aggregation, and marshaling/unmarshaling context across service boundaries.
-
Context in HTTP Servers & Service Calls — HTTP handler context:
r.Context()for request-scoped cancellation, middleware integration, and propagating to services. HTTP client patterns:NewRequestWithContext, client timeouts, and retries with context awareness. Database operations: always use*Contextvariants (QueryContext,ExecContext) to respect deadlines.
Cross-References
- → See the
samber/cc-skills-golang@golang-concurrencyskill for goroutine cancellation patterns using context - → See the
samber/cc-skills-golang@golang-databaseskill for context-aware database operations (QueryContext, ExecContext) - → See the
samber/cc-skills-golang@golang-observabilityskill for trace context propagation with OpenTelemetry - → See the
samber/cc-skills-golang@golang-design-patternsskill for timeout and resilience patterns
Enforce with Linters
Many context pitfalls are caught automatically by linters: govet, staticcheck. → See the samber/cc-skills-golang@golang-lint skill for configuration and usage.
相关技能
面向 Go 工程师的惯用错误处理实践,覆盖创建、包装、检查与结构化日志。
调试、编写和审查 Go 代码,覆盖 goroutine、错误处理、模块与标准库的实践指导。
在 Go 代码发布前捕获 panic、静默数据损坏与细微运行时 bug。
写出无泄漏、可正确退出与传递错误的 Go 并发代码,并审阅 PR 与代码库。
提供 Go 命名规范细则,涵盖包名、类型、错误、布尔、接收者、常量与测试。