What problem does context.Context solve, and what are its four methods?
context.Context carries three things across API boundaries and goroutines for the lifetime of one request or operation: a cancellation signal, an optional deadline, and request-scoped values. Before it existed, each library made up its own "quit channel" and timeout handling, so cancellation could not flow cleanly from an HTTP handler down to a DB driver.
type Context interface {
Deadline() (deadline time.Time, ok bool) // ok == false: no deadline
Done() <-chan struct{} // closed on cancel/timeout; nil if never cancelable
Err() error // nil until Done closes, then Canceled or DeadlineExceeded
Value(key any) any // request-scoped lookup
}
Key properties: contexts are immutable. You never change one; you derive a child with WithCancel, WithTimeout, WithValue and so on, which builds a tree. Cancellation flows down the tree, never up. All methods are safe to call from many goroutines at once.
What the interviewer is looking for: that context is for request lifetime and control flow, not a general dependency-injection bag. Also that Done() returning nil (for Background()) is fine inside a select, because receiving from a nil channel blocks forever.
More on Context
- Q260Explain how cancellation propagates through a context tree. What happens internally when a parent is canceled?
- Q261Why must you always call the CancelFunc, even if the operation finished successfully? What leaks if you don't?
- Q262WithTimeout vs WithDeadline: what is the difference, and what happens when a child asks for a later deadline than its parent?
- Q263What does this print?
- Q264What values can ctx.Err() return, and how should you check them?
- Q265What is WithCancelCause, and how does ctx.Err() differ from context.Cause(ctx)?