[英]terminating blocking goroutines with errgroup
我有兩個任務在 go 例程中運行。 我正在使用錯誤組。 我不確定如何正確使用 errgroup.WithContext。
在下面的代碼中,task1 正在返回錯誤,我想在發生這種情況時終止 task2(長時間運行)。 請注意,在此示例中添加 time.sleep 只是為了模擬我的問題。 實際上 task1 和 task2 正在做真正的工作並且沒有任何睡眠呼叫。
package main
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
"time"
)
func task1(ctx context.Context) error {
time.Sleep(5 * time.Second)
fmt.Println("first finished, pretend error happened")
return ctx.Err()
}
func task2(ctx context.Context) error {
select {
case <-ctx.Done():
fmt.Println("task 1 is finished with error")
return ctx.Err()
default:
fmt.Println("second started")
time.Sleep(50 * time.Second)
fmt.Println("second finished")
}
return nil
}
func test() (err error) {
ctx := context.Background()
g, gctx := errgroup.WithContext(ctx)
g.Go(func() error {
return task1(gctx)
})
g.Go(func() error {
return task2(gctx)
})
err = g.Wait()
if err != nil {
fmt.Println("wait done")
}
return err
}
func main() {
fmt.Println("main")
err := test()
if err != nil {
fmt.Println("main err")
fmt.Println(err.Error())
}
}
正確處理上下文取消而不是時間取決於您的任務。在time.Sleep
中睡覺。
如 errgroup 文檔中所述:
WithContext 返回一個新組和一個從 ctx 派生的關聯上下文。
派生的上下文在第一次傳遞給 Go 的 function 返回非零錯誤或第一次 Wait 返回時被取消,以先發生者為准。
您正在使用錯誤組,但您的上下文處理需要重構。
這是您的任務 2 的重構:
func task2(ctx context.Context) error {
errCh := make(chan bool)
go func() {
time.Sleep(50 * time.Second)
errCh <- true
}()
select {
case <-ctx.Done():
return fmt.Errorf("context done: %w", ctx.Err())
case <-errCh:
return errors.New("task 2 failed")
}
}
使用這樣的 select,您等待第一個通道發射。 在這種情況下,它是上下文過期,除非您將 time sleep 修改為更低。 示例游樂場。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.