Documentation ¶
Overview ¶
Package context implements a mechanism to carry data across API boundaries. The context.T struct carries deadlines and cancellation as well as other arbitrary values.
Application code receives contexts in two main ways:
1) A context.T is returned from v23.Init(). This will generally be used to set up servers in main, or for stand-alone client programs.
func main() { ctx, shutdown := v23.Init() defer shutdown() doSomething(ctx) }
2) A context.T is passed to every server method implementation as the first parameter.
func (m *myServer) Method(ctx *context.T, call rpc.ServerCall) error { doSomething(ctx) }
Once you have a context you can derive further contexts to change settings. for example to adjust a deadline you might do:
func main() { ctx, shutdown := v23.Init() defer shutdown() // We'll use cacheCtx to lookup data in memcache // if it takes more than a second to get data from // memcache we should just skip the cache and perform // the slow operation. cacheCtx, cancel := WithTimeout(ctx, time.Second) if err := FetchDataFromMemcache(cacheCtx, key); err != nil { // Here we use the original ctx, not the derived cacheCtx // so we aren't constrained by the 1 second timeout. RecomputeData(ctx, key) } }
Contexts form a tree where derived contexts are children of the contexts from which they were derived. Children inherit all the properties of their parent except for the property being replaced (the deadline in the example above).
Contexts are extensible. The Value/WithValue functions allow you to attach new information to the context and extend its capabilities. In the same way we derive new contexts via the 'With' family of functions you can create methods to attach new data:
package auth import "v.io/v23/context" type Auth struct{...} type key int const authKey = key(0) function WithAuth(parent *context.T, data *Auth) *context.T { return context.WithValue(parent, authKey, data) } function GetAuth(ctx *context.T) *Auth { data, _ := ctx.Value(authKey).(*Auth) return data }
Note that a value of any type can be used as a key, but you should use an unexported value of an unexported type to ensure that no collisions can occur.
Index ¶
- Variables
- func RootContext() (*T, CancelFunc)
- func WithCancel(parent *T) (*T, CancelFunc)
- func WithDeadline(parent *T, deadline time.Time) (*T, CancelFunc)
- func WithRootCancel(parent *T) (*T, CancelFunc)
- func WithTimeout(parent *T, timeout time.Duration) (*T, CancelFunc)
- type CancelFunc
- type ContextLogger
- type T
- func (t *T) Deadline() (deadline time.Time, ok bool)
- func (t *T) Done() <-chan struct{}
- func (t *T) Err() error
- func (t *T) Error(args ...interface{})
- func (t *T) ErrorDepth(depth int, args ...interface{})
- func (t *T) Errorf(format string, args ...interface{})
- func (t *T) Fatal(args ...interface{})
- func (t *T) FatalDepth(depth int, args ...interface{})
- func (t *T) Fatalf(format string, args ...interface{})
- func (t *T) FlushLog()
- func (t *T) Info(args ...interface{})
- func (t *T) InfoDepth(depth int, args ...interface{})
- func (t *T) InfoStack(all bool)
- func (t *T) Infof(format string, args ...interface{})
- func (t *T) Initialized() bool
- func (t *T) LoggerImplementation() interface{}
- func (t *T) Panic(args ...interface{})
- func (t *T) PanicDepth(depth int, args ...interface{})
- func (t *T) Panicf(format string, args ...interface{})
- func (t *T) V(level int) bool
- func (t *T) VDepth(depth int, level int) bool
- func (t *T) VI(level int) interface{ ... }
- func (t *T) VIDepth(depth int, level int) interface{ ... }
- func (t *T) Value(key interface{}) interface{}
Constants ¶
This section is empty.
Variables ¶
var Canceled = errors.New("context canceled")
Cancelled is returned by contexts which have been cancelled.
var DeadlineExceeded = errors.New("context deadline exceeded")
DeadlineExceeded is returned by contexts that have exceeded their deadlines and therefore been canceled automatically.
Functions ¶
func RootContext ¶
func RootContext() (*T, CancelFunc)
RootContext creates a new root context with no data attached. A RootContext is cancelable (see WithCancel). Typically you should not call this function, instead you should derive contexts from other contexts, such as the context returned from v23.Init or the result of the Context() method on a ServerCall. This function is sometimes useful in tests, where it is undesirable to initialize a runtime to test a function that reads from a T.
func WithCancel ¶
func WithCancel(parent *T) (*T, CancelFunc)
WithCancel returns a child of the current context along with a function that can be used to cancel it. After cancel() is called the channels returned by the Done() methods of the new context (and all context further derived from it) will be closed.
func WithDeadline ¶
func WithDeadline(parent *T, deadline time.Time) (*T, CancelFunc)
WithDeadline returns a child of the current context along with a function that can be used to cancel it at any time (as from WithCancel). When the deadline is reached the context will be automatically cancelled. Contexts should be cancelled when they are no longer needed so that resources associated with their timers may be released.
func WithRootCancel ¶
func WithRootCancel(parent *T) (*T, CancelFunc)
WithRootContext returns a context derived from parent, but that is detached from the deadlines and cancellation hierarchy so that this context will only ever be canceled when the returned CancelFunc is called, or the RootContext from which this context is ultimately derived is canceled.
func WithTimeout ¶
func WithTimeout(parent *T, timeout time.Duration) (*T, CancelFunc)
WithTimeout is similar to WithDeadline except a Duration is given that represents a relative point in time from now.
Types ¶
type CancelFunc ¶
type CancelFunc func()
CancelFunc is used to cancel a context. The first call will cause the paired context and all decendants to close their Done() channels. Further calls do nothing.
type ContextLogger ¶
type ContextLogger interface { // InfoDepth logs to the INFO log. depth is used to determine which call frame to log. InfoDepth(ctx *T, depth int, args ...interface{}) // InfoStack logs the current goroutine's stack if the all parameter // is false, or the stacks of all goroutines if it's true. InfoStack(ctx *T, all bool) // VDepth returns true if the configured logging level is greater than or equal to its parameter. depth // is used to determine which call frame to test against. VDepth(ctx *T, depth int, level int) bool // VIDepth is like VDepth, except that it returns nil if there level is greater than the // configured log level. VIDepth(ctx *T, depth int, level int) ContextLogger }
ContextLogger is a logger that uses a passed in T to configure the logging behavior.
type T ¶
type T struct {
// contains filtered or unexported fields
}
T carries deadlines, cancellation and data across API boundaries. It is safe to use a T from multiple goroutines simultaneously. The zero-type of context is uninitialized and will panic if used directly by application code. It also implements v23/logging.Logger and hence can be used directly for logging (e.g. ctx.Infof(...)).
func WithContextLogger ¶
func WithContextLogger(parent *T, logger ContextLogger) *T
WithContextLogger returns a child of the current context that embeds the supplied context logger
func WithLogger ¶
WithLogger returns a child of the current context that embeds the supplied logger.
func WithValue ¶
WithValue returns a child of the current context that will return the given val when Value(key) is called.
func (*T) Deadline ¶
Deadline returns the time at which this context will be automatically canceled.
func (*T) Done ¶
func (t *T) Done() <-chan struct{}
Done returns a channel which will be closed when this context.T is canceled or exceeds its deadline. Successive calls will return the same value. Implementations may return nil if they can never be canceled.
func (*T) Err ¶
After the channel returned by Done() is closed, Err() will return either Canceled or DeadlineExceeded.
func (*T) ErrorDepth ¶
func (*T) FatalDepth ¶
func (*T) Initialized ¶
Initialized returns true if this context has been properly initialized by a runtime.
func (*T) LoggerImplementation ¶
func (t *T) LoggerImplementation() interface{}
LoggerImplementation returns the implementation of the logger associated with this context. It should almost never need to be used by application code.
func (*T) PanicDepth ¶
func (*T) Value ¶
func (t *T) Value(key interface{}) interface{}
Value is used to carry data across API boundaries. This should be used only for data that is relevant across multiple API boundaries and not just to pass extra parameters to functions and methods. Any type that supports equality can be used as a key, but an unexported type should be used to prevent collisions.