Go context package
The context package is the canonical way to carry deadlines, cancellation signals, and request-scoped values across API boundaries and goroutines in Go. Pass a context as the first argument to every blocking function and you get free fan-out cancellation, timeout propagation, and graceful shutdown across your service tree.
1.Create a root context
Every context tree starts with context.Background() at the top of main or an incoming HTTP handler. Use context.TODO() only as a placeholder while you wire plumbing through legacy code paths.
2.Derive with cancellation or timeout
Wrap the root with WithCancel, WithTimeout, or WithDeadline to produce a child. The returned cancel function MUST be deferred immediately, even on the timeout variants, to release the goroutine that watches the parent.
3.Honor cancellation downstream
Every blocking call (HTTP, database, channel receive) should select on ctx.Done() and return ctx.Err() on wakeup. This is what turns cancellation into a real signal instead of a leaked goroutine.
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("upstream slow: %w", err)
}
return err
}
defer resp.Body.Close()