当等待组中的一个 goroutine 发生第一个错误时如何退出?
How to exit when the first error occurs for one of the goroutines within a wait Group?
func getRecords(ctx context.Context, ids *[]Id) error {
ctx, cancel := context.WithTimeout(ctx, DefaultTimeout)
defer cancel()
var wg sync.WaitGroup
size := len(*ids)
allErrors := make(chan error, size)
for i := 0; i < size; i++ {
wg.Add(1)
go func(x int){
err := //call to other func which return error type. nil or error
if err != nil { // I will be creating n goroutines. How to exit rightaway if one of
// them return error
allErrors <- err
}
wg.Done()
}(i)
}
go func() {
wg.Wait()
close(allErrors)
}
return nil
}
这里的匿名函数如何退出?
您需要使用ErrGroup
这就是ErrGroup.Go所做的
The first call to return a non-nil error cancels the group; its error
will be returned by Wait.
所以当任何一个goroutinereturn出错时,其他goroutines会自动取消。
用法:
errs, ctx = errgroup.WithContext(ctx)
for i := 0; i < size; i++ {
errs.Go( func() error{
...
})
}
if err := g.Wait(); err != nil {
// Handle Errors from GoRoutines
}
编辑:
也许答案不够详细。当文档说其他 goroutines 将被取消时,这意味着被 errGroup
编辑的 context
将被取消。所以每个 go routine owner 都必须在他们的代码中处理这个取消。
示例: https://go.dev/play/p/hXWjtN4uj06
现实世界的例子: 当你的 golang 服务启动时,也许你在一个例程中启动了一个 HTTP 服务器,在另一个例程中启动了一个 Kafka 消费者,并在最后一个例程中说了一个 grpc 服务器。现在,如果其中任何一个停止,您想要停止整个服务(考虑服务已关闭)。然后你与所有这些 goroutines 共享 errGroupd 上下文(幸运的是这些底层服务已经处理了这个上下文取消逻辑,所以你不必编写一个)但是如果那个 goroutine 做了一些自定义的事情那么它的 goroutine 所有者有责任处理取消信号
func getRecords(ctx context.Context, ids *[]Id) error {
ctx, cancel := context.WithTimeout(ctx, DefaultTimeout)
defer cancel()
var wg sync.WaitGroup
size := len(*ids)
allErrors := make(chan error, size)
for i := 0; i < size; i++ {
wg.Add(1)
go func(x int){
err := //call to other func which return error type. nil or error
if err != nil { // I will be creating n goroutines. How to exit rightaway if one of
// them return error
allErrors <- err
}
wg.Done()
}(i)
}
go func() {
wg.Wait()
close(allErrors)
}
return nil
}
这里的匿名函数如何退出?
您需要使用ErrGroup
这就是ErrGroup.Go所做的
The first call to return a non-nil error cancels the group; its error will be returned by Wait.
所以当任何一个goroutinereturn出错时,其他goroutines会自动取消。
用法:
errs, ctx = errgroup.WithContext(ctx)
for i := 0; i < size; i++ {
errs.Go( func() error{
...
})
}
if err := g.Wait(); err != nil {
// Handle Errors from GoRoutines
}
编辑:
也许答案不够详细。当文档说其他 goroutines 将被取消时,这意味着被 errGroup
编辑的 context
将被取消。所以每个 go routine owner 都必须在他们的代码中处理这个取消。
示例: https://go.dev/play/p/hXWjtN4uj06
现实世界的例子: 当你的 golang 服务启动时,也许你在一个例程中启动了一个 HTTP 服务器,在另一个例程中启动了一个 Kafka 消费者,并在最后一个例程中说了一个 grpc 服务器。现在,如果其中任何一个停止,您想要停止整个服务(考虑服务已关闭)。然后你与所有这些 goroutines 共享 errGroupd 上下文(幸运的是这些底层服务已经处理了这个上下文取消逻辑,所以你不必编写一个)但是如果那个 goroutine 做了一些自定义的事情那么它的 goroutine 所有者有责任处理取消信号