Context package for Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

GoA language context package can associate a set of functions that handle the same request with a goroutine context.Context variable of this type and provide a cancellation ( cancelation ) and timeout ( timeout ) mechanism. Personally, Sameer Ajmani this document: Cancelation, Context, and plumbing are written clearly and are easier to understand context package .

Update 1: The following Context definitions are selected from Go Concurrency patterns:context:

 //A Context carries A deadline, cancelation signal, and request-scoped values//across API boundaries. Its methods is safe for simultaneous use by multiple//Goroutines.type Context Interface {//Done returns a channel T    Hat is closed if this Context is a canceled//or times out.    Done () <-chan struct{}//ERR indicates why this context was canceled, after the Do channel//is closed.    ERR () error//Deadline returns the time when this Context would be is canceled, if any. Deadline () (Deadline time.    Time, OK bool)//value returns the value associated with key or nil if none. Value (Key interface{}) interface{}}  

The four functions are defined as follows:
A) The Done function returns a read channel -only, so only for its operation close . And this channel will only be in the Context cancel timeout case of being or close ;
b) Err is Done channel close after being used to obtain close the reason and returns a non-nil value of: context canceled or context deadline exceeded ;
c) Deadline returns Context cancel the time that was taken. If it is ok false , it indicates that there is no setting deadline ;
D) Value returns the same key bound value, if no corresponding value is returned nil .

Update 2: Simply analyze the source code:

// 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.type emptyCtx intfunc (*emptyCtx) Deadline() (deadline time.Time, ok bool) {    return}func (*emptyCtx) Done() <-chan struct{} {    return nil}func (*emptyCtx) Err() error {    return nil}func (*emptyCtx) Value(key interface{}) interface{} {    return nil}func (e *emptyCtx) String() string {    switch e {    case background:        return "context.Background"    case todo:        return "context.TODO"    }    return "unknown empty Context"}var (    background = new(emptyCtx)    todo   = new(emptyCtx))

context.Background()And context.TODO() What is returned is actually a emptyCtx pointer to the type variable.

Look again at the WithCancel() function implementation:

// 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.func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {    c := newCancelCtx(parent)    propagateCancel(parent, c)    return c, func() { c.cancel(true, Canceled) }}// newCancelCtx returns an initialized cancelCtx.func newCancelCtx(parent Context) *cancelCtx {    return &cancelCtx{        Context: parent,        done:    make(chan struct{}),    }}

And the cancelCtx definition is as follows:

// A cancelCtx can be canceled.  When canceled, it also cancels any children// that implement canceler.type cancelCtx struct {    Context    done chan struct{} // closed by the first cancel call.    mu       sync.Mutex    children map[canceler]bool // set to nil by the first cancel call    err      error             // set to non-nil by the first cancel call}

Each time the function is called WithCancel , the newly generated Context will contain " 父Context " and a new one done channel .

propagateCancel()The function is implemented as follows:

// propagateCancel arranges for child to be canceled when parent is.func propagateCancel(parent Context, child canceler) {    if parent.Done() == nil {        return // parent is never canceled    }    if p, ok := parentCancelCtx(parent); ok {        p.mu.Lock()        if p.err != nil {            // parent has already been canceled            child.cancel(false, p.err)        } else {            if p.children == nil {                p.children = make(map[canceler]bool)            }            p.children[child] = true        }        p.mu.Unlock()    } else {        go func() {            select {            case <-parent.Done():                child.cancel(false, parent.Err())            case <-child.Done():            }        }()    }}

This function is the addition of the newly generated Context 父Context children members, so as to form a "cascade" cancel operation.

Other References:
Package context,
Concurrent patterns in Golang:context;
context and cancellation of Goroutines.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.