|  | // Copyright 2016 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package context_test | 
|  |  | 
|  | import ( | 
|  | "context" | 
|  | "fmt" | 
|  | "time" | 
|  | ) | 
|  |  | 
|  | const shortDuration = 1 * time.Millisecond // a reasonable duration to block in an example | 
|  |  | 
|  | // This example demonstrates the use of a cancelable context to prevent a | 
|  | // goroutine leak. By the end of the example function, the goroutine started | 
|  | // by gen will return without leaking. | 
|  | func ExampleWithCancel() { | 
|  | // 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 | 
|  | } | 
|  | } | 
|  | // Output: | 
|  | // 1 | 
|  | // 2 | 
|  | // 3 | 
|  | // 4 | 
|  | // 5 | 
|  | } | 
|  |  | 
|  | // This example passes a context with an arbitrary deadline to tell a blocking | 
|  | // function that it should abandon its work as soon as it gets to it. | 
|  | func ExampleWithDeadline() { | 
|  | d := time.Now().Add(shortDuration) | 
|  | ctx, cancel := context.WithDeadline(context.Background(), d) | 
|  |  | 
|  | // Even though ctx will be expired, it is good practice to call its | 
|  | // cancellation 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()) | 
|  | } | 
|  |  | 
|  | // Output: | 
|  | // context deadline exceeded | 
|  | } | 
|  |  | 
|  | // This example passes a context with a timeout to tell a blocking function that | 
|  | // it should abandon its work after the timeout elapses. | 
|  | func ExampleWithTimeout() { | 
|  | // Pass a context with a timeout to tell a blocking function that it | 
|  | // should abandon its work after the timeout elapses. | 
|  | ctx, cancel := context.WithTimeout(context.Background(), shortDuration) | 
|  | defer cancel() | 
|  |  | 
|  | select { | 
|  | case <-time.After(1 * time.Second): | 
|  | fmt.Println("overslept") | 
|  | case <-ctx.Done(): | 
|  | fmt.Println(ctx.Err()) // prints "context deadline exceeded" | 
|  | } | 
|  |  | 
|  | // Output: | 
|  | // context deadline exceeded | 
|  | } | 
|  |  | 
|  | // This example demonstrates how a value can be passed to the context | 
|  | // and also how to retrieve it if it exists. | 
|  | func ExampleWithValue() { | 
|  | 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")) | 
|  |  | 
|  | // Output: | 
|  | // found value: Go | 
|  | // key not found: color | 
|  | } |