前言

目前,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"
}
}
]
}