What is the context package in Go and how do you use it for cancellation and deadlines?
go-mid-004
Your answer
Answer as you would in a real interview — explain your thinking, not just the conclusion.
Model answer
The context package provides a way to carry deadlines, cancellation signals, and request-scoped values across API boundaries and goroutines. context.Background() is the root (never cancelled). context.WithCancel returns a derived context and a cancel function — calling cancel propagates cancellation to all children. context.WithTimeout and context.WithDeadline automatically cancel after a duration or at a specific time. Every goroutine that does I/O or blocking work should accept a context.Context as its first parameter and check ctx.Done() to respect cancellation. Failing to cancel derived contexts causes goroutine and resource leaks. Values in context should be limited to request-scoped data (request IDs, auth tokens) and never used as a substitute for function parameters.
Code example
package main
import (
"context"
"fmt"
"time"
)
func fetchData(ctx context.Context, url string) (string, error) {
// Simulate a slow operation respecting context
select {
case <-time.After(500 * time.Millisecond):
return "data from " + url, nil
case <-ctx.Done():
return "", ctx.Err() // context.DeadlineExceeded or Canceled
}
}
func main() {
// Cancel after 200ms — fetchData will not complete in time
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel() // always defer cancel to free resources
result, err := fetchData(ctx, "https://example.com/api")
if err != nil {
fmt.Println("error:", err) // context deadline exceeded
return
}
fmt.Println(result)
}
Follow-up
What are the risks of storing mutable values in context, and how does the Context's value chain work (child inheriting parent's values)?