How could a Gopher not know the Go Context? Come and learn about it!

introduce

The Go 1.7 standard library introduces the context, which is the context of the Goroutine, including the running state, environment, site and other information of the Goroutine.

Context is used to pass context information between goroutines, including: cancel signal, timeout, expiration time, K-V, etc.

With the introduction of the Context package, many interfaces in the standard library have context parameters, such as the Database/SQL package. Context has become almost standard practice for concurrency control and timeout control.

Usage scenarios

In the Go HTTP package Server, each request has a corresponding Goroutine to handle. Request handlers typically start additional Goroutines to access back-end services, such as databases and RPC services. A Goroutine used to process a request usually requires access to some request-specific data, such as end-user authentication information, tokens associated with authentication, and request expiration time. When a request is cancelled or times out, all goroutines used to process the request should be quickly exited before the system can release the resources occupied by these Goroutines.

Use standard

  • Don’t putContextPut in a struct, insteadContextIt should be passed in as the first argument, namedctx, such as:
func DoSomething (CTX context.Context, arg arg) error {
    // use ctx
}
Copy the code
  • Never pass a nil Context even if the function allows it. If you don’t know which Context to use, you can use context.todo ().

  • The Value correlation method using Context should only be used for request-related metadata passed through programs and interfaces, not for optional parameters.

  • The same Context can be passed to different goroutines because the Context is concurrency safe.

The Context structure

// A Context carries a deadline, cancelation 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{}}Copy the code
  • Done()Return a channel. This is closed when times out or when the cancel method is called.
  • Err()Return an error. Why the context was cancelled.
  • Deadline()Returns the deadline and OK.
  • Value()returnKeyValue.

The context package method

func Background(a) Context
func TODO(a) Context

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key, val interface{}) Context
Copy the code
  • BackgroundTODOAll return emptyContext.
  • WithCancelWith a newDone channelReturn a parentContextA copy of the.
  • WithDeadlineThe deadline is adjusted not laterdeadlineReturns a copy of the parent context.
  • WithTimeoutreturnWithDeadline(parent, time.Now().Add(timeout)).
  • WithValueReturns the value associated with the parent key invalA copy of.

conclusion

The entire context package source code is very short, very easy to learn, be sure to read. In addition to using context to control concurrency, we can also use WaitGroup.