blob: 06580e0465aa107886b7bc2841bf135ece44b809 [file] [log] [blame]
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +00001// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package context defines the Context type, which carries deadlines,
6// cancelation signals, and other request-scoped values across API boundaries
7// and between processes.
8//
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -04009// Incoming requests to a server should create a Context, and outgoing
10// calls to servers should accept a Context. The chain of function
11// calls between them must propagate the Context, optionally replacing
12// it with a derived Context created using WithCancel, WithDeadline,
13// WithTimeout, or WithValue. When a Context is canceled, all
14// Contexts derived from it are also canceled.
Sameer Ajmanic4692da2016-06-14 16:48:42 -040015//
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -040016// The WithCancel, WithDeadline, and WithTimeout functions take a
17// Context (the parent) and return a derived Context (the child) and a
18// CancelFunc. Calling the CancelFunc cancels the child and its
19// children, removes the parent's reference to the child, and stops
20// any associated timers. Failing to call the CancelFunc leaks the
21// child and its children until the parent is canceled or the timer
22// fires. The go vet tool checks that CancelFuncs are used on all
23// control-flow paths.
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000024//
25// Programs that use Contexts should follow these rules to keep interfaces
26// consistent across packages and enable static analysis tools to check context
27// propagation:
28//
29// Do not store Contexts inside a struct type; instead, pass a Context
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -040030// explicitly to each function that needs it. The Context should be the first
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000031// parameter, typically named ctx:
32//
33// func DoSomething(ctx context.Context, arg Arg) error {
34// // ... use ctx ...
35// }
36//
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -040037// Do not pass a nil Context, even if a function permits it. Pass context.TODO
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000038// if you are unsure about which Context to use.
39//
40// Use context Values only for request-scoped data that transits processes and
41// APIs, not for passing optional parameters to functions.
42//
43// The same Context may be passed to functions running in different goroutines;
44// Contexts are safe for simultaneous use by multiple goroutines.
45//
Shenghou Ma0960c7c2016-05-05 14:22:34 -040046// See https://blog.golang.org/context for example code for a server that uses
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000047// Contexts.
48package context
49
50import (
51 "errors"
52 "fmt"
Brad Fitzpatrickbd724972016-04-10 15:45:34 +000053 "reflect"
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000054 "sync"
55 "time"
56)
57
58// A Context carries a deadline, a cancelation signal, and other values across
59// API boundaries.
60//
61// Context's methods may be called by multiple goroutines simultaneously.
62type Context interface {
63 // Deadline returns the time when work done on behalf of this context
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -040064 // should be canceled. Deadline returns ok==false when no deadline is
65 // set. Successive calls to Deadline return the same results.
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000066 Deadline() (deadline time.Time, ok bool)
67
68 // Done returns a channel that's closed when work done on behalf of this
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -040069 // context should be canceled. Done may return nil if this context can
70 // never be canceled. Successive calls to Done return the same value.
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000071 //
72 // WithCancel arranges for Done to be closed when cancel is called;
73 // WithDeadline arranges for Done to be closed when the deadline
74 // expires; WithTimeout arranges for Done to be closed when the timeout
75 // elapses.
76 //
77 // Done is provided for use in select statements:
78 //
79 // // Stream generates values with DoSomething and sends them to out
80 // // until DoSomething returns an error or ctx.Done is closed.
Brad Fitzpatrick87bca882016-04-26 18:54:12 -070081 // func Stream(ctx context.Context, out chan<- Value) error {
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000082 // for {
83 // v, err := DoSomething(ctx)
84 // if err != nil {
85 // return err
86 // }
87 // select {
88 // case <-ctx.Done():
89 // return ctx.Err()
90 // case out <- v:
91 // }
92 // }
93 // }
94 //
Shenghou Ma0960c7c2016-05-05 14:22:34 -040095 // See https://blog.golang.org/pipelines for more examples of how to use
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +000096 // a Done channel for cancelation.
97 Done() <-chan struct{}
98
Russ Cox6e2c4bc2017-04-10 21:09:13 -040099 // If Done is not yet closed, Err returns nil.
100 // If Done is closed, Err returns a non-nil error explaining why:
101 // Canceled if the context was canceled
102 // or DeadlineExceeded if the context's deadline passed.
103 // After Err returns a non-nil error, successive calls to Err return the same error.
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000104 Err() error
105
106 // Value returns the value associated with this context for key, or nil
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400107 // if no value is associated with key. Successive calls to Value with
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000108 // the same key returns the same result.
109 //
110 // Use context values only for request-scoped data that transits
111 // processes and API boundaries, not for passing optional parameters to
112 // functions.
113 //
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400114 // A key identifies a specific value in a Context. Functions that wish
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000115 // to store values in Context typically allocate a key in a global
116 // variable then use that key as the argument to context.WithValue and
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400117 // Context.Value. A key can be any type that supports equality;
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000118 // packages should define keys as an unexported type to avoid
119 // collisions.
120 //
121 // Packages that define a Context key should provide type-safe accessors
Kenny Grant04acd622016-05-31 22:30:37 +0100122 // for the values stored using that key:
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000123 //
124 // // Package user defines a User type that's stored in Contexts.
125 // package user
126 //
127 // import "context"
128 //
129 // // User is the type of value stored in the Contexts.
130 // type User struct {...}
131 //
132 // // key is an unexported type for keys defined in this package.
133 // // This prevents collisions with keys defined in other packages.
134 // type key int
135 //
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400136 // // userKey is the key for user.User values in Contexts. It is
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000137 // // unexported; clients use user.NewContext and user.FromContext
138 // // instead of using this key directly.
Michael Stapelberg2915e442017-08-30 07:50:13 -0700139 // var userKey key
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000140 //
141 // // NewContext returns a new Context that carries value u.
142 // func NewContext(ctx context.Context, u *User) context.Context {
143 // return context.WithValue(ctx, userKey, u)
144 // }
145 //
146 // // FromContext returns the User value stored in ctx, if any.
147 // func FromContext(ctx context.Context) (*User, bool) {
148 // u, ok := ctx.Value(userKey).(*User)
149 // return u, ok
150 // }
151 Value(key interface{}) interface{}
152}
153
154// Canceled is the error returned by Context.Err when the context is canceled.
155var Canceled = errors.New("context canceled")
156
157// DeadlineExceeded is the error returned by Context.Err when the context's
158// deadline passes.
Brad Fitzpatrickdc4427f2016-05-19 18:08:43 +0000159var DeadlineExceeded error = deadlineExceededError{}
160
161type deadlineExceededError struct{}
162
Russ Coxf69991c2016-10-04 23:58:42 -0400163func (deadlineExceededError) Error() string { return "context deadline exceeded" }
164func (deadlineExceededError) Timeout() bool { return true }
165func (deadlineExceededError) Temporary() bool { return true }
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000166
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400167// An emptyCtx is never canceled, has no values, and has no deadline. It is not
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000168// struct{}, since vars of this type must have distinct addresses.
169type emptyCtx int
170
171func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
172 return
173}
174
175func (*emptyCtx) Done() <-chan struct{} {
176 return nil
177}
178
179func (*emptyCtx) Err() error {
180 return nil
181}
182
183func (*emptyCtx) Value(key interface{}) interface{} {
184 return nil
185}
186
187func (e *emptyCtx) String() string {
188 switch e {
189 case background:
190 return "context.Background"
191 case todo:
192 return "context.TODO"
193 }
194 return "unknown empty Context"
195}
196
197var (
198 background = new(emptyCtx)
199 todo = new(emptyCtx)
200)
201
202// Background returns a non-nil, empty Context. It is never canceled, has no
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400203// values, and has no deadline. It is typically used by the main function,
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000204// initialization, and tests, and as the top-level Context for incoming
205// requests.
206func Background() Context {
207 return background
208}
209
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400210// TODO returns a non-nil, empty Context. Code should use context.TODO when
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000211// it's unclear which Context to use or it is not yet available (because the
212// surrounding function has not yet been extended to accept a Context
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400213// parameter). TODO is recognized by static analysis tools that determine
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000214// whether Contexts are propagated correctly in a program.
215func TODO() Context {
216 return todo
217}
218
219// A CancelFunc tells an operation to abandon its work.
220// A CancelFunc does not wait for the work to stop.
221// After the first call, subsequent calls to a CancelFunc do nothing.
222type CancelFunc func()
223
224// WithCancel returns a copy of parent with a new Done channel. The returned
225// context's Done channel is closed when the returned cancel function is called
226// or when the parent context's Done channel is closed, whichever happens first.
227//
228// Canceling this context releases resources associated with it, so code should
229// call cancel as soon as the operations running in this Context complete.
230func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
231 c := newCancelCtx(parent)
232 propagateCancel(parent, &c)
233 return &c, func() { c.cancel(true, Canceled) }
234}
235
236// newCancelCtx returns an initialized cancelCtx.
237func newCancelCtx(parent Context) cancelCtx {
Josh Bleecher Snyder986768d2017-01-08 13:22:24 -0800238 return cancelCtx{Context: parent}
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000239}
240
241// propagateCancel arranges for child to be canceled when parent is.
242func propagateCancel(parent Context, child canceler) {
243 if parent.Done() == nil {
244 return // parent is never canceled
245 }
246 if p, ok := parentCancelCtx(parent); ok {
247 p.mu.Lock()
248 if p.err != nil {
249 // parent has already been canceled
250 child.cancel(false, p.err)
251 } else {
252 if p.children == nil {
Jack Lindamood39382792016-07-26 14:20:36 -0700253 p.children = make(map[canceler]struct{})
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000254 }
Jack Lindamood39382792016-07-26 14:20:36 -0700255 p.children[child] = struct{}{}
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000256 }
257 p.mu.Unlock()
258 } else {
259 go func() {
260 select {
261 case <-parent.Done():
262 child.cancel(false, parent.Err())
263 case <-child.Done():
264 }
265 }()
266 }
267}
268
269// parentCancelCtx follows a chain of parent references until it finds a
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400270// *cancelCtx. This function understands how each of the concrete types in this
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000271// package represents its parent.
272func parentCancelCtx(parent Context) (*cancelCtx, bool) {
273 for {
274 switch c := parent.(type) {
275 case *cancelCtx:
276 return c, true
277 case *timerCtx:
278 return &c.cancelCtx, true
279 case *valueCtx:
280 parent = c.Context
281 default:
282 return nil, false
283 }
284 }
285}
286
287// removeChild removes a context from its parent.
288func removeChild(parent Context, child canceler) {
289 p, ok := parentCancelCtx(parent)
290 if !ok {
291 return
292 }
293 p.mu.Lock()
294 if p.children != nil {
295 delete(p.children, child)
296 }
297 p.mu.Unlock()
298}
299
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400300// A canceler is a context type that can be canceled directly. The
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000301// implementations are *cancelCtx and *timerCtx.
302type canceler interface {
303 cancel(removeFromParent bool, err error)
304 Done() <-chan struct{}
305}
306
Josh Bleecher Snyder986768d2017-01-08 13:22:24 -0800307// closedchan is a reusable closed channel.
308var closedchan = make(chan struct{})
309
310func init() {
311 close(closedchan)
312}
313
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400314// A cancelCtx can be canceled. When canceled, it also cancels any children
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000315// that implement canceler.
316type cancelCtx struct {
317 Context
318
Josh Bleecher Snyder986768d2017-01-08 13:22:24 -0800319 mu sync.Mutex // protects following fields
320 done chan struct{} // created lazily, closed by first cancel call
Jack Lindamood39382792016-07-26 14:20:36 -0700321 children map[canceler]struct{} // set to nil by the first cancel call
322 err error // set to non-nil by the first cancel call
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000323}
324
325func (c *cancelCtx) Done() <-chan struct{} {
Josh Bleecher Snyder986768d2017-01-08 13:22:24 -0800326 c.mu.Lock()
327 if c.done == nil {
328 c.done = make(chan struct{})
329 }
330 d := c.done
331 c.mu.Unlock()
332 return d
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000333}
334
335func (c *cancelCtx) Err() error {
336 c.mu.Lock()
337 defer c.mu.Unlock()
338 return c.err
339}
340
341func (c *cancelCtx) String() string {
342 return fmt.Sprintf("%v.WithCancel", c.Context)
343}
344
345// cancel closes c.done, cancels each of c's children, and, if
346// removeFromParent is true, removes c from its parent's children.
347func (c *cancelCtx) cancel(removeFromParent bool, err error) {
348 if err == nil {
349 panic("context: internal error: missing cancel error")
350 }
351 c.mu.Lock()
352 if c.err != nil {
353 c.mu.Unlock()
354 return // already canceled
355 }
356 c.err = err
Josh Bleecher Snyder986768d2017-01-08 13:22:24 -0800357 if c.done == nil {
358 c.done = closedchan
359 } else {
360 close(c.done)
361 }
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000362 for child := range c.children {
363 // NOTE: acquiring the child's lock while holding parent's lock.
364 child.cancel(false, err)
365 }
366 c.children = nil
367 c.mu.Unlock()
368
369 if removeFromParent {
370 removeChild(c.Context, c)
371 }
372}
373
374// WithDeadline returns a copy of the parent context with the deadline adjusted
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400375// to be no later than d. If the parent's deadline is already earlier than d,
376// WithDeadline(parent, d) is semantically equivalent to parent. The returned
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000377// context's Done channel is closed when the deadline expires, when the returned
378// cancel function is called, or when the parent context's Done channel is
379// closed, whichever happens first.
380//
381// Canceling this context releases resources associated with it, so code should
382// call cancel as soon as the operations running in this Context complete.
Michael Darakanandaeca45992017-09-21 10:25:35 +1000383func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
384 if cur, ok := parent.Deadline(); ok && cur.Before(d) {
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000385 // The current deadline is already sooner than the new one.
386 return WithCancel(parent)
387 }
388 c := &timerCtx{
389 cancelCtx: newCancelCtx(parent),
Michael Darakanandaeca45992017-09-21 10:25:35 +1000390 deadline: d,
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000391 }
392 propagateCancel(parent, c)
Michael Darakanandaeca45992017-09-21 10:25:35 +1000393 dur := time.Until(d)
394 if dur <= 0 {
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000395 c.cancel(true, DeadlineExceeded) // deadline has already passed
396 return c, func() { c.cancel(true, Canceled) }
397 }
398 c.mu.Lock()
399 defer c.mu.Unlock()
400 if c.err == nil {
Michael Darakanandaeca45992017-09-21 10:25:35 +1000401 c.timer = time.AfterFunc(dur, func() {
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000402 c.cancel(true, DeadlineExceeded)
403 })
404 }
405 return c, func() { c.cancel(true, Canceled) }
406}
407
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400408// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
409// implement Done and Err. It implements cancel by stopping its timer then
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000410// delegating to cancelCtx.cancel.
411type timerCtx struct {
412 cancelCtx
413 timer *time.Timer // Under cancelCtx.mu.
414
415 deadline time.Time
416}
417
418func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
419 return c.deadline, true
420}
421
422func (c *timerCtx) String() string {
Brad Fitzpatrick298791a2016-08-30 01:05:18 +0000423 return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, time.Until(c.deadline))
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000424}
425
426func (c *timerCtx) cancel(removeFromParent bool, err error) {
427 c.cancelCtx.cancel(false, err)
428 if removeFromParent {
429 // Remove this timerCtx from its parent cancelCtx's children.
430 removeChild(c.cancelCtx.Context, c)
431 }
432 c.mu.Lock()
433 if c.timer != nil {
434 c.timer.Stop()
435 c.timer = nil
436 }
437 c.mu.Unlock()
438}
439
440// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
441//
442// Canceling this context releases resources associated with it, so code should
443// call cancel as soon as the operations running in this Context complete:
444//
445// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
446// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
447// defer cancel() // releases resources if slowOperation completes before timeout elapses
448// return slowOperation(ctx)
449// }
450func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
451 return WithDeadline(parent, time.Now().Add(timeout))
452}
453
454// WithValue returns a copy of parent in which the value associated with key is
455// val.
456//
457// Use context Values only for request-scoped data that transits processes and
458// APIs, not for passing optional parameters to functions.
Brad Fitzpatrickbd724972016-04-10 15:45:34 +0000459//
Brad Fitzpatrickc921d8f2016-11-11 23:40:25 +0000460// The provided key must be comparable and should not be of type
461// string or any other built-in type to avoid collisions between
462// packages using context. Users of WithValue should define their own
463// types for keys. To avoid allocating when assigning to an
464// interface{}, context keys often have concrete type
465// struct{}. Alternatively, exported context key variables' static
466// type should be a pointer or interface.
Brad Fitzpatrickbd724972016-04-10 15:45:34 +0000467func WithValue(parent Context, key, val interface{}) Context {
Brad Fitzpatrickc884f652016-04-28 22:04:30 -0500468 if key == nil {
469 panic("nil key")
470 }
Brad Fitzpatrickbd724972016-04-10 15:45:34 +0000471 if !reflect.TypeOf(key).Comparable() {
472 panic("key is not comparable")
473 }
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000474 return &valueCtx{parent, key, val}
475}
476
Sameer Ajmanie4dc7f12016-06-24 10:48:06 -0400477// A valueCtx carries a key-value pair. It implements Value for that key and
Brad Fitzpatrick9db7ef52016-03-08 00:07:18 +0000478// delegates all other calls to the embedded Context.
479type valueCtx struct {
480 Context
481 key, val interface{}
482}
483
484func (c *valueCtx) String() string {
485 return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
486}
487
488func (c *valueCtx) Value(key interface{}) interface{} {
489 if c.key == key {
490 return c.val
491 }
492 return c.Context.Value(key)
493}