Go Language-context Context Practice

Source: Internet
Author: User

Packages that use Context need to follow the following guidelines to satisfy interface consistency and facilitate static analysis

1. Do not place the Context in a struct, explicitly passing in the function. The Context variable needs to be used as the first parameter, generally named CTX

2. Even if the method allows, do not pass in a nil context, if you are not sure what you want to use the context of the time to pass a context. Todo

3. The Value-related method using the context should only be used for metadata that is passed in the program and interface and requested, and should not be used to pass some optional arguments

4. The same context can be used to transfer to different goroutine, the context is safe in multiple goroutine

Method description
    • The Done method returns a close Channel,close channel as a broadcast notification when the context is canceled or timeout, telling the context related function to stop the current work and then return.

When a parent operation initiates a goroutine for a child operation, these sub-operation cannot be removed from the parent operation. The Withcancel function described below provides a way to cancel the newly created context.

The context can be safely used by multiple goroutine. Developers can pass a context to any number of goroutine and then cancel the context to be able to notify all goroutine.

    • The Err method returns why the context was canceled.

    • Deadline returns when the context will time out.

    • Value returns context-dependent data.
    • The context package has provided us with two, one is Background (), one is TODO (), and both functions return an instance of the context. Just the two instances returned are empty Context. Backgound is the root of all the context and cannot be cancel.
Example 1

This example passes a context, which has an arbitrary cutoff period, which tells a blocking function that once it reaches it, it should abandon its work.

package mainimport (    "context"    "fmt"    "time")func main() {    d := time.Now().Add(50 * time.Millisecond)    ctx, cancel := context.WithDeadline(context.Background(),d)    // Even though ctx will be expired, it is good practice to call its    // cancelation 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())    }}

Run results

context deadline exceeded
Example 2
package mainimport (    "context"    "fmt"    "time")func main() {    d := time.Now().Add(50 * time.Second)    ctx, cancel := context.WithDeadline(context.Background(),d)    // Even though ctx will be expired, it is good practice to call its    // cancelation 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())    }}

Run results

overslept
Example 3
package mainimport (    "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        }    }}

Run results

12345
Example 4
package mainimport (    "fmt"    "context")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"))}

Run results

found value: Gokey not found: color
Example 5
package mainimport (    "fmt"    "context")func main() {    f := func(ctx context.Context, k string) {        if v := ctx.Value(k); v != nil {            fmt.Println("found value:", v)            return        }        fmt.Println("key not found:", k)    }    ctx := context.WithValue(context.Background(), "language", "Go")    f(ctx, "language")    f(ctx, "color")}

Run results

found value: Gokey not found: color

Go Language-context Context Practice

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.