| | |
| | |
| | |
| |
|
| | package context_test |
| |
|
| | import ( |
| | "context" |
| | "errors" |
| | "fmt" |
| | "net" |
| | "sync" |
| | "time" |
| | ) |
| |
|
| | var neverReady = make(chan struct{}) |
| |
|
| | |
| | |
| | |
| | func ExampleWithCancel() { |
| | |
| | |
| | |
| | |
| | |
| | gen := func(ctx context.Context) <-chan int { |
| | dst := make(chan int) |
| | n := 1 |
| | go func() { |
| | for { |
| | select { |
| | case <-ctx.Done(): |
| | return |
| | case dst <- n: |
| | n++ |
| | } |
| | } |
| | }() |
| | return dst |
| | } |
| |
|
| | ctx, cancel := context.WithCancel(context.Background()) |
| | defer cancel() |
| |
|
| | for n := range gen(ctx) { |
| | fmt.Println(n) |
| | if n == 5 { |
| | break |
| | } |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | } |
| |
|
| | |
| | |
| | func ExampleWithDeadline() { |
| | d := time.Now().Add(shortDuration) |
| | ctx, cancel := context.WithDeadline(context.Background(), d) |
| |
|
| | |
| | |
| | |
| | defer cancel() |
| |
|
| | select { |
| | case <-neverReady: |
| | fmt.Println("ready") |
| | case <-ctx.Done(): |
| | fmt.Println(ctx.Err()) |
| | } |
| |
|
| | |
| | |
| | } |
| |
|
| | |
| | |
| | func ExampleWithTimeout() { |
| | |
| | |
| | ctx, cancel := context.WithTimeout(context.Background(), shortDuration) |
| | defer cancel() |
| |
|
| | select { |
| | case <-neverReady: |
| | fmt.Println("ready") |
| | case <-ctx.Done(): |
| | fmt.Println(ctx.Err()) |
| | } |
| |
|
| | |
| | |
| | } |
| |
|
| | |
| | |
| | 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")) |
| |
|
| | |
| | |
| | |
| | } |
| |
|
| | |
| | |
| | func ExampleAfterFunc_cond() { |
| | waitOnCond := func(ctx context.Context, cond *sync.Cond, conditionMet func() bool) error { |
| | stopf := context.AfterFunc(ctx, func() { |
| | |
| | |
| | |
| | cond.L.Lock() |
| | defer cond.L.Unlock() |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | cond.Broadcast() |
| | }) |
| | defer stopf() |
| |
|
| | |
| | |
| | |
| | for !conditionMet() { |
| | cond.Wait() |
| | if ctx.Err() != nil { |
| | return ctx.Err() |
| | } |
| | } |
| |
|
| | return nil |
| | } |
| |
|
| | cond := sync.NewCond(new(sync.Mutex)) |
| |
|
| | var wg sync.WaitGroup |
| | for i := 0; i < 4; i++ { |
| | wg.Add(1) |
| | go func() { |
| | defer wg.Done() |
| |
|
| | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) |
| | defer cancel() |
| |
|
| | cond.L.Lock() |
| | defer cond.L.Unlock() |
| |
|
| | err := waitOnCond(ctx, cond, func() bool { return false }) |
| | fmt.Println(err) |
| | }() |
| | } |
| | wg.Wait() |
| |
|
| | |
| | |
| | |
| | |
| | |
| | } |
| |
|
| | |
| | |
| | func ExampleAfterFunc_connection() { |
| | readFromConn := func(ctx context.Context, conn net.Conn, b []byte) (n int, err error) { |
| | stopc := make(chan struct{}) |
| | stop := context.AfterFunc(ctx, func() { |
| | conn.SetReadDeadline(time.Now()) |
| | close(stopc) |
| | }) |
| | n, err = conn.Read(b) |
| | if !stop() { |
| | |
| | |
| | <-stopc |
| | conn.SetReadDeadline(time.Time{}) |
| | return n, ctx.Err() |
| | } |
| | return n, err |
| | } |
| |
|
| | listener, err := net.Listen("tcp", "localhost:0") |
| | if err != nil { |
| | fmt.Println(err) |
| | return |
| | } |
| | defer listener.Close() |
| |
|
| | conn, err := net.Dial(listener.Addr().Network(), listener.Addr().String()) |
| | if err != nil { |
| | fmt.Println(err) |
| | return |
| | } |
| | defer conn.Close() |
| |
|
| | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) |
| | defer cancel() |
| |
|
| | b := make([]byte, 1024) |
| | _, err = readFromConn(ctx, conn, b) |
| | fmt.Println(err) |
| |
|
| | |
| | |
| | } |
| |
|
| | |
| | |
| | func ExampleAfterFunc_merge() { |
| | |
| | |
| | mergeCancel := func(ctx, cancelCtx context.Context) (context.Context, context.CancelFunc) { |
| | ctx, cancel := context.WithCancelCause(ctx) |
| | stop := context.AfterFunc(cancelCtx, func() { |
| | cancel(context.Cause(cancelCtx)) |
| | }) |
| | return ctx, func() { |
| | stop() |
| | cancel(context.Canceled) |
| | } |
| | } |
| |
|
| | ctx1, cancel1 := context.WithCancelCause(context.Background()) |
| | defer cancel1(errors.New("ctx1 canceled")) |
| |
|
| | ctx2, cancel2 := context.WithCancelCause(context.Background()) |
| |
|
| | mergedCtx, mergedCancel := mergeCancel(ctx1, ctx2) |
| | defer mergedCancel() |
| |
|
| | cancel2(errors.New("ctx2 canceled")) |
| | <-mergedCtx.Done() |
| | fmt.Println(context.Cause(mergedCtx)) |
| |
|
| | |
| | |
| | } |
| |
|