【发布时间】:2020-08-17 19:27:07
【问题描述】:
我对 golang 及其并发原则还很陌生。我的用例涉及对一批实体执行多个 http 请求(针对单个实体)。如果某个实体的任何 http 请求失败,我需要停止它的所有并行 http 请求。此外,我必须管理因错误而失败的实体的数量。我正在尝试在实体goroutines中实现errorgroup,这样如果单个实体的任何http请求失败,errorgroup就会终止并将错误返回给它的父goroutine。但我不确定如何保持错误计数。
func main(entity[] string) {
errorC := make(chan string) // channel to insert failed entity
var wg sync.WaitGroup
for _, link := range entity {
wg.Add(1)
// Spawn errorgroup here. errorgroup_spawn
}
go func() {
wg.Wait()
close(errorC)
}()
for msg := range errorC {
// here storing error entityIds somewhere.
}
}
和这样的错误组
func errorgroup_spawn(ctx context.Context, errorC chan string, wg *sync.WaitGroup) { // and other params
defer (*wg).Done()
goRoutineCollection, ctxx := errgroup.WithContext(ctx)
results := make(chan *result)
goRoutineCollection.Go(func() error {
// http calls for single entity
// if error occurs, push it in errorC, and return Error.
return nil
})
go func() {
goRoutineCollection.Wait()
close(result)
}()
return goRoutineCollection.Wait()
}
PS:我也在考虑应用嵌套错误组,但在运行其他错误组时无法考虑维护错误计数 谁能指导我,这是处理此类现实世界场景的正确方法吗?
【问题讨论】:
-
单个实体的 http 调用是并发的还是顺序的?如果并发,可能会有多个错误,您是对一个错误感兴趣,还是对所有错误感兴趣?
-
@BurakSerdar 它们是并发的,是的,可能存在多个错误。但是 errorgroup 在遇到第一个错误时立即终止。
-
有多种方法可以做到这一点。一种方法是传递一个包含错误通道的错误和实体名称的错误结构。另一种方法是为 goroutine 运行 https 调用并侦听错误的每个实体使用一个结构,并将错误放入该结构中的一个字段中。
-
@BurakSerdar 你能详细说明一下第一种方式吗?对于第二种方式,您是否暗示嵌套的 goroutines,其中内部 goroutines 将更新外部提供的结构中的错误?
-
另外,首先@BurakSerdar 有两件事,我在上面的问题中的方法是否合适?其次,如果可能的话,你能说明嵌套错误组的例子吗?