Golang 增强版waitgroup
原创
©著作权归作者所有:来自51CTO博客作者fwhezfwhez的原创作品,请联系作者获取转载授权,否则将追究法律责任
前言
目前,golang官方的sync.WaitGroup,只有同步作用,缺少了对子任务执行的结果上下文信息。
特此,设计了高仿sdk wgx,目前已投入线上使用
介绍
wgx 是对sync.WaitGroup的增强版,解决sync.WaitGroup的以下问题:
- sync.WaitGroup只确保子任务被执行,无法传递任务最终的执行结果。wgx支持三个执行结果[全失败,全成功,半失败半成功]。
- sync.WaitGroup不关注子任务的上下文细节,也不关注失败和成功的计数。wgx支持对失败的任务,进行上下文输出(失败个数, 失败原因,失败场景敲定, 失败链路补回)。
使用
package main
import (
"encoding/json"
"fmt"
"github.com/fwhezfwhez/wgx"
"runtime"
)
func main() {
wg := wgx.NewWaitGroup()
for i := 0; i < 10000; i ++ {
wg.Add(1)
go func(i int) {
defer func() {
switch i % 4 {
case 0:
wg.DoneSuccess()
case 1:
wg.DoneFail()
case 2:
wg.DoneFailWithSceneArgs("login_log_insert", map[string]interface{}{
"loc": here(),
"uname": "ft",
})
case 3:
wg.DoneFailWithErr("login_log_update", fmt.Errorf("redis err"))
}
}()
fmt.Println(1)
}(i)
}
rs := wg.Wait()
fmt.Println(JSON(rs))
}
func here() string {
_, f, l, _ := runtime.Caller(1)
return fmt.Sprintf("%s:%d", f, l)
}
func JSON(i interface{}) string {
r, _ := json.MarshalIndent(i, " ", " ")
return string(r)
}
返回结果包含了以下字段
type Result struct {
ResultState int `json:"result_state"` // 执行结果. 1全部失败,2全部成功,3混合
TotalCount int `json:"total_count"` // 总个数, 调用wg.Add(delta)的累计值
SuccessCount int `json:"success_count"` // 成功数量, 调用wg.Done/wg.DoneSuccess时计数+1
FailCount int `json:"fail_count"` // 失败个数, 调用wg.Fail/wg.FailWithSceneArgs计数+1
Panels []ReasonPanel `json:"panels"` // 结果面板, 会按照失败场景,对失败原因进行上下文结果.
}
样例
{
"result_state": 3,
"total_count": 10000,
"success_count": 2500,
"fail_count": 7500,
"panels": [
{
"scene": "login_log_insert",
"args": {
"err": {},
"loc": "G:/go_workspace/GOPATH/src/wgx/wait-group_test.go:23",
"location": "G:/go_workspace/GOPATH/src/wgx/wait-group_test.go:22",
"uname": "ft"
}
},
{
"scene": "G:/go_workspace/GOPATH/src/wgx/wait-group_test.go:20",
"args": {
"location": "G:/go_workspace/GOPATH/src/wgx/wait-group_test.go:20"
}
},
{
"scene": "login_log_update",
"args": {
"error": "redis err",
"location": "G:/go_workspace/GOPATH/src/wgx/wait-group_test.go:29"
}
}
]
}