Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
example_test.go264 linesDownload Raw Back to context
1// Copyright 2016 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package context_test6 7import (8	"context"9	"errors"10	"fmt"11	"net"12	"sync"13	"time"14)15 16var neverReady = make(chan struct{}) // never closed17 18// This example demonstrates the use of a cancelable context to prevent a19// goroutine leak. By the end of the example function, the goroutine started20// by gen will return without leaking.21func ExampleWithCancel() {22	// gen generates integers in a separate goroutine and23	// sends them to the returned channel.24	// The callers of gen need to cancel the context once25	// they are done consuming generated integers not to leak26	// the internal goroutine started by gen.27	gen := func(ctx context.Context) <-chan int {28		dst := make(chan int)29		n := 130		go func() {31			for {32				select {33				case <-ctx.Done():34					return // returning not to leak the goroutine35				case dst <- n:36					n++37				}38			}39		}()40		return dst41	}42 43	ctx, cancel := context.WithCancel(context.Background())44	defer cancel() // cancel when we are finished consuming integers45 46	for n := range gen(ctx) {47		fmt.Println(n)48		if n == 5 {49			break50		}51	}52	// Output:53	// 154	// 255	// 356	// 457	// 558}59 60// This example passes a context with an arbitrary deadline to tell a blocking61// function that it should abandon its work as soon as it gets to it.62func ExampleWithDeadline() {63	d := time.Now().Add(shortDuration)64	ctx, cancel := context.WithDeadline(context.Background(), d)65 66	// Even though ctx will be expired, it is good practice to call its67	// cancellation function in any case. Failure to do so may keep the68	// context and its parent alive longer than necessary.69	defer cancel()70 71	select {72	case <-neverReady:73		fmt.Println("ready")74	case <-ctx.Done():75		fmt.Println(ctx.Err())76	}77 78	// Output:79	// context deadline exceeded80}81 82// This example passes a context with a timeout to tell a blocking function that83// it should abandon its work after the timeout elapses.84func ExampleWithTimeout() {85	// Pass a context with a timeout to tell a blocking function that it86	// should abandon its work after the timeout elapses.87	ctx, cancel := context.WithTimeout(context.Background(), shortDuration)88	defer cancel()89 90	select {91	case <-neverReady:92		fmt.Println("ready")93	case <-ctx.Done():94		fmt.Println(ctx.Err()) // prints "context deadline exceeded"95	}96 97	// Output:98	// context deadline exceeded99}100 101// This example demonstrates how a value can be passed to the context102// and also how to retrieve it if it exists.103func ExampleWithValue() {104	type favContextKey string105 106	f := func(ctx context.Context, k favContextKey) {107		if v := ctx.Value(k); v != nil {108			fmt.Println("found value:", v)109			return110		}111		fmt.Println("key not found:", k)112	}113 114	k := favContextKey("language")115	ctx := context.WithValue(context.Background(), k, "Go")116 117	f(ctx, k)118	f(ctx, favContextKey("color"))119 120	// Output:121	// found value: Go122	// key not found: color123}124 125// This example uses AfterFunc to define a function which waits on a sync.Cond,126// stopping the wait when a context is canceled.127func ExampleAfterFunc_cond() {128	waitOnCond := func(ctx context.Context, cond *sync.Cond, conditionMet func() bool) error {129		stopf := context.AfterFunc(ctx, func() {130			// We need to acquire cond.L here to be sure that the Broadcast131			// below won't occur before the call to Wait, which would result132			// in a missed signal (and deadlock).133			cond.L.Lock()134			defer cond.L.Unlock()135 136			// If multiple goroutines are waiting on cond simultaneously,137			// we need to make sure we wake up exactly this one.138			// That means that we need to Broadcast to all of the goroutines,139			// which will wake them all up.140			//141			// If there are N concurrent calls to waitOnCond, each of the goroutines142			// will spuriously wake up O(N) other goroutines that aren't ready yet,143			// so this will cause the overall CPU cost to be O(N²).144			cond.Broadcast()145		})146		defer stopf()147 148		// Since the wakeups are using Broadcast instead of Signal, this call to149		// Wait may unblock due to some other goroutine's context being canceled,150		// so to be sure that ctx is actually canceled we need to check it in a loop.151		for !conditionMet() {152			cond.Wait()153			if ctx.Err() != nil {154				return ctx.Err()155			}156		}157 158		return nil159	}160 161	cond := sync.NewCond(new(sync.Mutex))162 163	var wg sync.WaitGroup164	for i := 0; i < 4; i++ {165		wg.Add(1)166		go func() {167			defer wg.Done()168 169			ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)170			defer cancel()171 172			cond.L.Lock()173			defer cond.L.Unlock()174 175			err := waitOnCond(ctx, cond, func() bool { return false })176			fmt.Println(err)177		}()178	}179	wg.Wait()180 181	// Output:182	// context deadline exceeded183	// context deadline exceeded184	// context deadline exceeded185	// context deadline exceeded186}187 188// This example uses AfterFunc to define a function which reads from a net.Conn,189// stopping the read when a context is canceled.190func ExampleAfterFunc_connection() {191	readFromConn := func(ctx context.Context, conn net.Conn, b []byte) (n int, err error) {192		stopc := make(chan struct{})193		stop := context.AfterFunc(ctx, func() {194			conn.SetReadDeadline(time.Now())195			close(stopc)196		})197		n, err = conn.Read(b)198		if !stop() {199			// The AfterFunc was started.200			// Wait for it to complete, and reset the Conn's deadline.201			<-stopc202			conn.SetReadDeadline(time.Time{})203			return n, ctx.Err()204		}205		return n, err206	}207 208	listener, err := net.Listen("tcp", "localhost:0")209	if err != nil {210		fmt.Println(err)211		return212	}213	defer listener.Close()214 215	conn, err := net.Dial(listener.Addr().Network(), listener.Addr().String())216	if err != nil {217		fmt.Println(err)218		return219	}220	defer conn.Close()221 222	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)223	defer cancel()224 225	b := make([]byte, 1024)226	_, err = readFromConn(ctx, conn, b)227	fmt.Println(err)228 229	// Output:230	// context deadline exceeded231}232 233// This example uses AfterFunc to define a function which combines234// the cancellation signals of two Contexts.235func ExampleAfterFunc_merge() {236	// mergeCancel returns a context that contains the values of ctx,237	// and which is canceled when either ctx or cancelCtx is canceled.238	mergeCancel := func(ctx, cancelCtx context.Context) (context.Context, context.CancelFunc) {239		ctx, cancel := context.WithCancelCause(ctx)240		stop := context.AfterFunc(cancelCtx, func() {241			cancel(context.Cause(cancelCtx))242		})243		return ctx, func() {244			stop()245			cancel(context.Canceled)246		}247	}248 249	ctx1, cancel1 := context.WithCancelCause(context.Background())250	defer cancel1(errors.New("ctx1 canceled"))251 252	ctx2, cancel2 := context.WithCancelCause(context.Background())253 254	mergedCtx, mergedCancel := mergeCancel(ctx1, ctx2)255	defer mergedCancel()256 257	cancel2(errors.New("ctx2 canceled"))258	<-mergedCtx.Done()259	fmt.Println(context.Cause(mergedCtx))260 261	// Output:262	// ctx2 canceled263}264 
codekingpro/portable-devtools · Team Ai