1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package context_test 6 7 import ( 8 "context" 9 "fmt" 10 "time" 11 ) 12 13 // This example demonstrates the use of a cancelable context to prevent a 14 // goroutine leak. By the end of the example function, the goroutine started 15 // by gen will return without leaking. 16 func ExampleWithCancel() { 17 // gen generates integers in a separate goroutine and 18 // sends them to the returned channel. 19 // The callers of gen need to cancel the context once 20 // they are done consuming generated integers not to leak 21 // the internal goroutine started by gen. 22 gen := func(ctx context.Context) <-chan int { 23 dst := make(chan int) 24 n := 1 25 go func() { 26 for { 27 select { 28 case <-ctx.Done(): 29 return // returning not to leak the goroutine 30 case dst <- n: 31 n++ 32 } 33 } 34 }() 35 return dst 36 } 37 38 ctx, cancel := context.WithCancel(context.Background()) 39 defer cancel() // cancel when we are finished consuming integers 40 41 for n := range gen(ctx) { 42 fmt.Println(n) 43 if n == 5 { 44 break 45 } 46 } 47 // Output: 48 // 1 49 // 2 50 // 3 51 // 4 52 // 5 53 } 54 55 // This example passes a context with an arbitrary deadline to tell a blocking 56 // function that it should abandon its work as soon as it gets to it. 57 func ExampleWithDeadline() { 58 d := time.Now().Add(50 * time.Millisecond) 59 ctx, cancel := context.WithDeadline(context.Background(), d) 60 61 // Even though ctx will be expired, it is good practice to call its 62 // cancelation function in any case. Failure to do so may keep the 63 // context and its parent alive longer than necessary. 64 defer cancel() 65 66 select { 67 case <-time.After(1 * time.Second): 68 fmt.Println("overslept") 69 case <-ctx.Done(): 70 fmt.Println(ctx.Err()) 71 } 72 73 // Output: 74 // context deadline exceeded 75 } 76 77 // This example passes a context with a timeout to tell a blocking function that 78 // it should abandon its work after the timeout elapses. 79 func ExampleWithTimeout() { 80 // Pass a context with a timeout to tell a blocking function that it 81 // should abandon its work after the timeout elapses. 82 ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) 83 defer cancel() 84 85 select { 86 case <-time.After(1 * time.Second): 87 fmt.Println("overslept") 88 case <-ctx.Done(): 89 fmt.Println(ctx.Err()) // prints "context deadline exceeded" 90 } 91 92 // Output: 93 // context deadline exceeded 94 } 95 96 func ExampleWithValue() { 97 type favContextKey string 98 99 f := func(ctx context.Context, k favContextKey) { 100 if v := ctx.Value(k); v != nil { 101 fmt.Println("found value:", v) 102 return 103 } 104 fmt.Println("key not found:", k) 105 } 106 107 k := favContextKey("language") 108 ctx := context.WithValue(context.Background(), k, "Go") 109 110 f(ctx, k) 111 f(ctx, favContextKey("color")) 112 113 // Output: 114 // found value: Go 115 // key not found: color 116 } 117