Chapter 14: Context Package
Context Package
Section titled “Context Package”The context package is essential for managing cancellation, deadlines, and request-scoped values across API boundaries and goroutines. It’s the standard way to control the lifetime of operations in Go.
Context is Go’s answer to a fundamental question: how do you propagate cancellation and deadlines through a call graph? When a user cancels a request, how does that signal reach every goroutine working on that request? Context provides a standard, composable solution.
Introduced in Go 1.7 and now ubiquitous in Go APIs, context forms a tree structure where parent cancellation automatically propagates to children. This cascading cancellation prevents resource leaks and ensures graceful shutdowns.
This chapter covers context creation, cancellation patterns, timeouts, deadlines, and request-scoped values. You’ll learn when to use context, how to propagate it correctly, and common pitfalls to avoid.
Why Context?
Section titled “Why Context?”The Problems Context Solves
Section titled “The Problems Context Solves”When handling requests (HTTP, gRPC, database queries), you often need to:
- Cancel work when a request is cancelled: User closes browser, don’t waste resources
- Set timeouts for operations: Prevent operations from running forever
- Pass request-scoped data: User ID, trace ID, authentication tokens across the call stack
Without context, these are hard problems. Cancellation requires passing done channels everywhere. Timeouts need manual timer management. Request data either goes in globals (bad) or requires threading through every function signature (tedious).
Context solves all three elegantly. It’s passed as the first parameter to functions, carrying cancellation signals, deadlines, and values. The pattern is universal across the Go ecosystem.
Creating Contexts
Section titled “Creating Contexts”Background and TODO
Section titled “Background and TODO”context.Background() is the root context, typically used in main, init, or tests:
WithCancel
Section titled “WithCancel”WithCancel returns a derived context that can be cancelled:
WithTimeout and WithDeadline
Section titled “WithTimeout and WithDeadline”Set automatic cancellation after a duration or at a specific time:
WithValue
Section titled “WithValue”Pass request-scoped values through the context:
Context in HTTP Handlers
Section titled “Context in HTTP Handlers”Every HTTP request comes with a context:
Propagating Context
Section titled “Propagating Context”Always pass context as the first parameter:
Context Best Practices
Section titled “Context Best Practices”Don’ts
Section titled “Don’ts”Cancellation Patterns
Section titled “Cancellation Patterns”Cancel Multiple Goroutines
Section titled “Cancel Multiple Goroutines”First Result Wins
Section titled “First Result Wins”Key Takeaways
Section titled “Key Takeaways”- Always pass context as the first parameter named
ctx - Use
WithCancelfor manual cancellation of goroutines - Use
WithTimeout/WithDeadlinefor automatic time-based cancellation - Use
WithValuesparingly - only for request-scoped data - Always call cancel (usually with
defer cancel()) - Check
ctx.Done()in loops and long operations - Never store context in structs - pass it per-call
- Use custom types for keys to avoid collisions
Exercise
Section titled “Exercise”Create a rate-limited API client that respects context cancellation:
Context-Aware API Client
Implement a simple API client that fetches data with rate limiting and respects context cancellation/timeouts.