A `context.Context` carries a deadline, a cancellation signal, and values across API boundaries. Passing one to a function does not automatically stop that function: the function must respond to cancellation, and the caller must consider when the context itself will end. section 8.6 section 8.6.4
The interface exposes four ways to inspect that state:
- `Deadline` reports whether a deadline is set; `Done` supplies a receive-only channel that closes when work should stop. section 9.1 section 8.6.4
- `Err` is nil before `Done` closes and then explains why, such as `context.Canceled` or `context.DeadlineExceeded`; `Value` retrieves a value by key. section 8.6.4 section 9.1
Stop a file watcher
Create a context with `context.WithCancel(context.Background())`, pass it to a file watcher running in a goroutine, and defer the returned cancel function. Cancellation gives the watcher a signal to close its file descriptor when the surrounding work ends. section 8.6.2
func f(ctx context.Context) error {
// ...
select { #1
case <-ctx.Done():
return ctx.Err()
case ch1 <- struct{}{}:
}
select { #2
case <-ctx.Done():
return ctx.Err()
case v := <-ch2:
// ...
}
}
A blocking channel send or receive can keep a function waiting after its context is canceled. Put each channel operation in a `select` with `ctx.Done()`, returning `ctx.Err()` when cancellation wins. section 8.6.4
Do not pass an HTTP request context blindly
An asynchronous publish started by an HTTP handler may outlive the response. Passing `r.Context()` to it creates a race: writing the response cancels the request context, potentially interrupting publication. If publication should continue after the response, `context.Background()` avoids that cancellation but also drops request values. A context wrapper can instead suppress the parent deadline and cancellation while forwarding `Value`; choose that behavior only when retaining those values is needed. section 9.1






