Context超时处理应该这么做

火山方舟向量数据库大模型
超时处理应该这么做

1、超时处理有问题代码

只通过select监听超时信号,没有处理正常逻辑处理。

  
package main  
  
import (  
 "context"  
 "fmt"  
 "sync"  
 "time"  
)  
  
var wg sync.WaitGroup  
  
func main() {  
 // 定义一个3s超时context 所有衍生出来的goroutine必须在3s内完成 否则会cancel掉  
 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)  
 defer cancel()  
  
 go func() {  
  wg.Add(2)  
  go watch(ctx, 1)  
  go watch(ctx, 2)  
  wg.Wait()  
 }()  
  
// 这里有问题,因为不管是超时还是未超时都会进入<-ctx.Done() 也就是都会等待3s 这不是我们想要的  
 select {  
 case <-ctx.Done():  
  fmt.Printf("watch %d %s\n", 0, ctx.Err())  
 }  
  
 fmt.Println("finished")  
}  
  
func watch(ctx context.Context, flag int) {  
 defer wg.Done()  
  
 func() {  
  fmt.Printf("doing something flag:%d\n", flag)  
  time.Sleep(10*time.Second)  
  fmt.Println("finished flag:", flag)  
 }()  
}  

2、如何解决?

很简单,就是在所有goroutine结束之后发送一个done信号给主goroutine,这样select就会监听到这个信号,从而安全退出。

  
// 增加done信号  
 done := make(chan struct{})  
 go func() {  
  wg.Add(2)  
  go watch(ctx, 1)  
  go watch(ctx, 2)  
  wg.Wait()  
  done <- struct{}{} // 发送done信号  
 }()  
  
 select {  
 case <-done: // 接受done信号  
  fmt.Println("Done")  
 case <-ctx.Done():  
  fmt.Printf("watch %d %s\n", 0, ctx.Err())  
 }  

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生可观测性技术的落地实践
云原生技术和理念在近几年成为了备受关注的话题。应用通过云原生改造,变得更动态、弹性,可以更好地利用云的弹性能力。但是动态、弹性的环境也给应用以及基础设施的观测带来了更大的挑战。本次分享主要介绍了云原生社区中可观测性相关的技术和工具,以及如何使用这些工具来完成对云原生环境的观测。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论