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.
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