Created
September 26, 2020 02:02
-
-
Save yrong/db2e77e86f62740d7b87ff3874d2c994 to your computer and use it in GitHub Desktop.
golang context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment