The Go Blog
Go Concurrency Patterns: Context
Introduction
In Go servers, each incoming request is handled in its own goroutine. Request handlers often start additional goroutines to access backends such as databases and RPC services. The set of goroutines working on a request typically needs access to request-specific values such as the identity of the end user, authorization tokens, and the request’s deadline. When a request is canceled or times out, all the goroutines working on that request should exit quickly so the system can reclaim any resources they are using.
At Google, we developed a context package that makes it easy to pass
request-scoped values, cancellation signals, and deadlines across API boundaries
to all the goroutines involved in handling a request.
The package is publicly available as
context.
This article describes how to use the package and provides a complete working
example.
Context
The core of the context package is the Context type:
// A Context carries a deadline, cancellation signal, and request-scoped values // across API boundaries. Its methods are safe for simultaneous use by multiple // goroutines. type Context interface { // Done returns a channel that is closed when this Context is canceled // or times out. Done() <-chan struct{} // Err indicates why this context was canceled, after the Done channel // is closed. Err() error // Deadline returns the time when this Context will be canceled, if any. Deadline() (deadline time.Time, ok bool) // Value returns the value associated with key or nil if none. Value(key interface{}) interface{} }
(This description is condensed; the godoc is authoritative.)
The Done method returns a channel that acts as a cancellation signal to
functions running on behalf of the Context: when the channel is closed, the
functions should abandon their work and return.
The Err method returns an error indicating why the Context was canceled.
The Pipelines and Cancellation article discusses the Done
channel idiom in more detail.
A Context does not have a Cancel method for the same reason the Done
channel is receive-only: the function receiving a cancellation signal is usually
not the one that sends the signal.
In particular, when a parent operation starts goroutines for sub-operations,
those sub-operations should not be able to cancel the parent.
Instead, the WithCancel function (described below) provides a way to cancel a
new Context value.
A Context is safe for simultaneous use by multiple goroutines.
Code can pass a single Context to any number of goroutines and cancel that
Context to signal all of them.
The Deadline method allows functions to determine whether they should start
work at all; if too little time is left, it may not be worthwhile.
Code may also use a deadline to set timeouts for I/O operations.
Value allows a