Involved Source Files
Package context defines the Context type, which carries deadlines,
cancellation signals, and other request-scoped values across API boundaries
and between processes.
Incoming requests to a server should create a Context, and outgoing
calls to servers should accept a Context. The chain of function
calls between them must propagate the Context, optionally replacing
it with a derived Context created using WithCancel, WithDeadline,
WithTimeout, or WithValue. When a Context is canceled, all
Contexts derived from it are also canceled.
The WithCancel, WithDeadline, and WithTimeout functions take a
Context (the parent) and return a derived Context (the child) and a
CancelFunc. Calling the CancelFunc cancels the child and its
children, removes the parent's reference to the child, and stops
any associated timers. Failing to call the CancelFunc leaks the
child and its children until the parent is canceled or the timer
fires. The go vet tool checks that CancelFuncs are used on all
control-flow paths.
Programs that use Contexts should follow these rules to keep interfaces
consistent across packages and enable static analysis tools to check context
propagation:
Do not store Contexts inside a struct type; instead, pass a Context
explicitly to each function that needs it. The Context should be the first
parameter, typically named ctx:
func DoSomething(ctx context.Context, arg Arg) error {
// ... use ctx ...
}
Do not pass a nil Context, even if a function permits it. Pass context.TODO
if you are unsure about which Context to use.
Use context Values only for request-scoped data that transits processes and
APIs, not for passing optional parameters to functions.
The same Context may be passed to functions running in different goroutines;
Contexts are safe for simultaneous use by multiple goroutines.
See https://blog.golang.org/context for example code for a server that uses
Contexts.
Code Examples
package main
import (
"context"
"fmt"
)
func main() {
// gen generates integers in a separate goroutine and
// sends them to the returned channel.
// The callers of gen need to cancel the context once
// they are done consuming generated integers not to leak
// the internal goroutine started by gen.
gen := func(ctx context.Context) <-chan int {
dst := make(chan int)
n := 1
go func() {
for {
select {
case <-ctx.Done():
return // returning not to leak the goroutine
case dst <- n:
n++
}
}
}()
return dst
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished consuming integers
for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
break
}
}
}
package main
import (
"context"
"fmt"
"time"
)
const shortDuration = 1 * time.Millisecond
func main() {
d := time.Now().Add(shortDuration)
ctx, cancel := context.WithDeadline(context.Background(), d)
// Even though ctx will be expired, it is good practice to call its
// cancellation function in any case. Failure to do so may keep the
// context and its parent alive longer than necessary.
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
package main
import (
"context"
"fmt"
"time"
)
const shortDuration = 1 * time.Millisecond
func main() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
ctx, cancel := context.WithTimeout(context.Background(), shortDuration)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err()) // prints "context deadline exceeded"
}
}
package main
import (
"context"
"fmt"
)
func main() {
type favContextKey string
f := func(ctx context.Context, k favContextKey) {
if v := ctx.Value(k); v != nil {
fmt.Println("found value:", v)
return
}
fmt.Println("key not found:", k)
}
k := favContextKey("language")
ctx := context.WithValue(context.Background(), k, "Go")
f(ctx, k)
f(ctx, favContextKey("color"))
}
Package-Level Type Names (total 9, in which 2 are exported)
/* sort exporteds by: | */
A CancelFunc tells an operation to abandon its work.
A CancelFunc does not wait for the work to stop.
A CancelFunc may be called by multiple goroutines simultaneously.
After the first call, subsequent calls to a CancelFunc do nothing.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
A cancelCtx can be canceled. When canceled, it also cancels any children
that implement canceler.
ContextContext
// set to nil by the first cancel call
// created lazily, closed by first cancel call
// set to non-nil by the first cancel call
// protects following fields
Deadline returns the time when work done on behalf of this context
should be canceled. Deadline returns ok==false when no deadline is
set. Successive calls to Deadline return the same results.
(*T) Done() <-chan struct{}(*T) Err() error(*T) String() string(*T) Value(key interface{}) interface{}
cancel closes c.done, cancels each of c's children, and, if
removeFromParent is true, removes c from its parent's children.
*T : Context
*T : fmt.Stringer
*T : canceler
*T : stringer
*T : runtime.stringer
func newCancelCtx(parent Context) cancelCtx
func parentCancelCtx(parent Context) (*cancelCtx, bool)
A canceler is a context type that can be canceled directly. The
implementations are *cancelCtx and *timerCtx.
( T) Done() <-chan struct{}( T) cancel(removeFromParent bool, err error)
*cancelCtx
*timerCtx
func propagateCancel(parent Context, child canceler)
func removeChild(parent Context, child canceler)
An emptyCtx is never canceled, has no values, and has no deadline. It is not
struct{}, since vars of this type must have distinct addresses.
(*T) Deadline() (deadline time.Time, ok bool)(*T) Done() <-chan struct{}(*T) Err() error(*T) String() string(*T) Value(key interface{}) interface{}
*T : Context
*T : fmt.Stringer
*T : stringer
*T : runtime.stringer
var background *emptyCtx
var todo *emptyCtx
A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
implement Done and Err. It implements cancel by stopping its timer then
delegating to cancelCtx.cancel.
cancelCtx.ContextContextcancelCtxcancelCtx
// set to nil by the first cancel call
// created lazily, closed by first cancel call
// set to non-nil by the first cancel call
// protects following fields
deadlinetime.Time
// Under cancelCtx.mu.
(*T) Deadline() (deadline time.Time, ok bool)(*T) Done() <-chan struct{}(*T) Err() error(*T) String() string(*T) Value(key interface{}) interface{}(*T) cancel(removeFromParent bool, err error)
*T : Context
*T : fmt.Stringer
*T : canceler
*T : stringer
*T : runtime.stringer
A valueCtx carries a key-value pair. It implements Value for that key and
delegates all other calls to the embedded Context.
ContextContextkeyinterface{}valinterface{}
Deadline returns the time when work done on behalf of this context
should be canceled. Deadline returns ok==false when no deadline is
set. Successive calls to Deadline return the same results.
Done returns a channel that's closed when work done on behalf of this
context should be canceled. Done may return nil if this context can
never be canceled. Successive calls to Done return the same value.
The close of the Done channel may happen asynchronously,
after the cancel function returns.
WithCancel arranges for Done to be closed when cancel is called;
WithDeadline arranges for Done to be closed when the deadline
expires; WithTimeout arranges for Done to be closed when the timeout
elapses.
Done is provided for use in select statements:
// Stream generates values with DoSomething and sends them to out
// until DoSomething returns an error or ctx.Done is closed.
func Stream(ctx context.Context, out chan<- Value) error {
for {
v, err := DoSomething(ctx)
if err != nil {
return err
}
select {
case <-ctx.Done():
return ctx.Err()
case out <- v:
}
}
}
See https://blog.golang.org/pipelines for more examples of how to use
a Done channel for cancellation.
If Done is not yet closed, Err returns nil.
If Done is closed, Err returns a non-nil error explaining why:
Canceled if the context was canceled
or DeadlineExceeded if the context's deadline passed.
After Err returns a non-nil error, successive calls to Err return the same error.
(*T) String() string(*T) Value(key interface{}) interface{}
*T : Context
*T : fmt.Stringer
*T : stringer
*T : runtime.stringer
Package-Level Functions (total 13, in which 6 are exported)
Background returns a non-nil, empty Context. It is never canceled, has no
values, and has no deadline. It is typically used by the main function,
initialization, and tests, and as the top-level Context for incoming
requests.
TODO returns a non-nil, empty Context. Code should use context.TODO when
it's unclear which Context to use or it is not yet available (because the
surrounding function has not yet been extended to accept a Context
parameter).
WithCancel returns a copy of parent with a new Done channel. The returned
context's Done channel is closed when the returned cancel function is called
or when the parent context's Done channel is closed, whichever happens first.
Canceling this context releases resources associated with it, so code should
call cancel as soon as the operations running in this Context complete.
WithDeadline returns a copy of the parent context with the deadline adjusted
to be no later than d. If the parent's deadline is already earlier than d,
WithDeadline(parent, d) is semantically equivalent to parent. The returned
context's Done channel is closed when the deadline expires, when the returned
cancel function is called, or when the parent context's Done channel is
closed, whichever happens first.
Canceling this context releases resources associated with it, so code should
call cancel as soon as the operations running in this Context complete.
WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
Canceling this context releases resources associated with it, so code should
call cancel as soon as the operations running in this Context complete:
func slowOperationWithTimeout(ctx context.Context) (Result, error) {
ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel() // releases resources if slowOperation completes before timeout elapses
return slowOperation(ctx)
}
WithValue returns a copy of parent in which the value associated with key is
val.
Use context Values only for request-scoped data that transits processes and
APIs, not for passing optional parameters to functions.
The provided key must be comparable and should not be of type
string or any other built-in type to avoid collisions between
packages using context. Users of WithValue should define their own
types for keys. To avoid allocating when assigning to an
interface{}, context keys often have concrete type
struct{}. Alternatively, exported context key variables' static
type should be a pointer or interface.
parentCancelCtx returns the underlying *cancelCtx for parent.
It does this by looking up parent.Value(&cancelCtxKey) to find
the innermost enclosing *cancelCtx and then checking whether
parent.Done() matches that *cancelCtx. (If not, the *cancelCtx
has been wrapped in a custom implementation providing a
different done channel, in which case we should not bypass it.)
propagateCancel arranges for child to be canceled when parent is.
removeChild removes a context from its parent.
stringify tries a bit to stringify v, without using fmt, since we don't
want context depending on the unicode tables. This is only used by
*valueCtx.String().
Package-Level Variables (total 7, in which 2 are exported)
Canceled is the error returned by Context.Err when the context is canceled.
DeadlineExceeded is the error returned by Context.Err when the context's
deadline passes.
The pages are generated with Goldsv0.4.2. (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.