我正在学习golang,在上下文环境中使用errgroup包时感到困惑。下面是我的简单代码:
package main
import (
"context"
"errors"
"fmt"
"time"
"golang.org/x/sync/errgroup"
)
func main() {
fmt.Println("..................")
ctx := context.Background()
group, ctx := errgroup.WithContext(ctx)
ctx, cancel := context.WithCancel(ctx)
group.Go(func() error {
//return errors.New("Error 1")
time.Sleep(8 * time.Second)
fmt.Println("Sleep 1 ended..................")
cancel()
return errors.New("Error 1")
})
group.Go(func() error {
//return errors.New("Error 1")
time.Sleep(2 * time.Second)
fmt.Println("Sleep 2 ended..................")
cancel()
return errors.New("Error 2")
})
err := group.Wait()
if err != nil {
fmt.Println("Error: ", err)
}
fmt.Println("..................")
}
输出结果如预期:
..................
Sleep 2 ended..................
Sleep 1 ended..................
Error: Error 2
..................
group.wait()“阻塞,直到Go方法的所有函数调用都返回,然后返回它们的第一个非空错误(如果有的话)。”
1.如果我想使用errgroup,但又想等到所有Go方法共享的上下文被取消,或者Go方法的所有函数调用都返回之后,该怎么办?
1.如果我想使用errgroup,但又想等到Go方法返回错误,那么哪个方法会取消上下文,而不是等待所有操作完成呢?
不知何故,我觉得errgroup包在使用上限制太多了。我遗漏了什么?
2条答案
按热度按时间yfwxisqw1#
这似乎不能仅仅通过使用
errGroup
本身来实现。1.也许这里可以使用
waitGroup
。1.可能只有在发生错误时才调用
cancel
。或者使用error
通道并等待直到出现第一个错误。yrefmtwq2#
此实现回答了您的两个问题:
它将打印以下内容:
返回一个错误会隐式地取消上下文,你需要等待
ctx.Done()
显式地放弃go例程的执行。使用
time.Sleep
可能被认为是一种反模式,因为它不确认上下文取消用途: