diff --git a/syncs/group.go b/syncs/group.go new file mode 100644 index 000000000..2a41aa5bb --- /dev/null +++ b/syncs/group.go @@ -0,0 +1,46 @@ +package syncs + +import ( + "context" + + "golang.org/x/sync/errgroup" +) + +// ErrGroup is a collection of goroutines working on subtasks that +// are part of the same overall task. +// +// Refers: +// +// https://github.com/neilotoole/errgroup +// https://github.com/fatih/semgroup +type ErrGroup struct { + *errgroup.Group +} + +// NewCtxErrGroup instance +func NewCtxErrGroup(ctx context.Context, limit ...int) (*ErrGroup, context.Context) { + egg, ctx1 := errgroup.WithContext(ctx) + if len(limit) > 0 && limit[0] > 0 { + egg.SetLimit(limit[0]) + } + + eg := &ErrGroup{Group: egg} + return eg, ctx1 +} + +// NewErrGroup instance +func NewErrGroup(limit ...int) *ErrGroup { + eg := &ErrGroup{Group: new(errgroup.Group)} + + if len(limit) > 0 && limit[0] > 0 { + eg.SetLimit(limit[0]) + } + return eg +} + +// Add one or more handler at once +func (g *ErrGroup) Add(handlers ...func() error) { + for _, handler := range handlers { + g.Go(handler) + } +} diff --git a/syncs/group_test.go b/syncs/group_test.go new file mode 100644 index 000000000..cdf7560a5 --- /dev/null +++ b/syncs/group_test.go @@ -0,0 +1,33 @@ +package syncs_test + +import ( + "fmt" + "testing" + + "github.com/gookit/goutil" + "github.com/gookit/goutil/netutil/httpreq" + "github.com/gookit/goutil/testutil" + "github.com/gookit/goutil/testutil/assert" +) + +func TestNewErrGroup(t *testing.T) { + httpreq.SetTimeout(3000) + + eg := goutil.NewErrGroup() + eg.Add(func() error { + resp, err := httpreq.Get(testSrvAddr + "/get") + if err != nil { + return err + } + + fmt.Println(testutil.ParseBodyToReply(resp.Body)) + return nil + }, func() error { + resp := httpreq.MustResp(httpreq.Post(testSrvAddr+"/post", "hi")) + fmt.Println(testutil.ParseBodyToReply(resp.Body)) + return nil + }) + + err := eg.Wait() + assert.NoErr(t, err) +} diff --git a/syncs/syncs_test.go b/syncs/syncs_test.go new file mode 100644 index 000000000..719e349d1 --- /dev/null +++ b/syncs/syncs_test.go @@ -0,0 +1,19 @@ +package syncs_test + +import ( + "fmt" + "testing" + + "github.com/gookit/goutil/testutil" +) + +var testSrvAddr string + +func TestMain(m *testing.M) { + s := testutil.NewEchoServer() + defer s.Close() + testSrvAddr = "http://" + s.Listener.Addr().String() + fmt.Println("Test server listen on:", testSrvAddr) + + m.Run() +}