github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/context/example_test.go (about)

     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 a 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  }