当前位置:网站首页>Usage scenarios of golang context

Usage scenarios of golang context

2022-07-05 06:12:00 Dawnlighttt


1. Value passed


Value passing is just context An auxiliary function of , Not the core function . Usually we only use context To pass optional data that does not affect the main business logic , Like log information 、 Debugging information, meta information, etc .


package main

import (
	"context"
	"fmt"
)

func readContext(ctx context.Context) {
    
	traceId, ok := ctx.Value("key").(string)
	if ok {
    
		fmt.Println("readContext key=", traceId)i
	} else {
    
		fmt.Println("readContext no key")
	}
}

func main() {
    
	ctx := context.Background()
	readContext(ctx)
	ctx = context.WithValue(ctx, "key", "beautiful")
	readContext(ctx)
}

In the use of WithValue Yes ctx When packing , You can set a key-value Key value pair , stay goroutine Passed between .


2. Timeout control


http Request to set timeout

package main

import (
	"context"
	"fmt"
	"time"
)

func httpRequest(ctx context.Context) {
    
	for {
    
		//  Handle http request 
		select {
    
		case <- ctx.Done():
			fmt.Println("Request timed out")
			return
		case <- time.After(time.Second):
			fmt.Println("Loading...")
		}
	}
}

func main() {
    
	fmt.Println("start TestTimeoutContext")
	ctx, cancel := context.WithTimeout(context.Background(), time.Second * 3)
	defer cancel()
	httpRequest(ctx)
	time.Sleep(time.Second * 5)
}

//start TestTimeoutContext
//Loading...
//Loading...
//Request timed out


file io Or the Internet io Wait for time-consuming operations , You can check whether the remaining time is sufficient , Decide whether to proceed to the next step

package main

import (
	"context"
	"fmt"
	"time"
)

func copyFile(ctx context.Context)  {
    
	deadline, ok := ctx.Deadline()
	if ok == false {
    
		return
	}
	// deadline.Sub(time.Now())  The difference between the deadline and the current time 
	isEnough := deadline.Sub(time.Now()) > time.Second * 5
	if isEnough {
    
		fmt.Println("copy file")
	} else {
    
		fmt.Println("isEnough is false return")
		return
	}
}

func main() {
    
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second * 4))
	defer cancel()
	copyFile(ctx)
	time.Sleep(time.Second * 5)
}


//isEnough is false return


3. Cancel control


goroutine Send a cancellation signal , Ensure that the logic emanates from yourself goroutine All cancelled successfully

package main

import (
	"context"
	"fmt"
	"time"
)

func gen(ctx context.Context) <-chan int {
    
	ch := make(chan int)
	go func() {
    
		var n int
		for {
    
			select {
    
			case ch <- n:
				n++
				time.Sleep(time.Second)
			case <-ctx.Done():
				return
			}
		}
	}()
	return ch
}

func main() {
    
	//  Create a Cancel context
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	for n := range gen(ctx) {
    
		fmt.Println(n)
		if n == 5 {
    
			//  Trigger after meeting the requirements cancel
			cancel()
			break
		}
	}
}
//0
//1
//2
//3
//4
//5


Reference material :

https://zhuanlan.zhihu.com/p/378711421

原网站

版权声明
本文为[Dawnlighttt]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140620216047.html