Source file src/context/example_test.go

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

View as plain text