// Package chitian/errgroup is an extension of the sync/errgroup which has this header comment: // // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package errgroup
import ( "context" "log" "runtime" "sync" ) type Error string
func(e Error) Error() string { returnstring(e) }
const ( PanicError = Error("errgroup: goroutine panic") ) // A Group is a collection of goroutines working on subtasks that are part of // the same overall task. // // A zero Group is valid and does not cancel on error. type Group struct { doneOnce sync.Once done chanstruct{}
// Not Recommended, just to be compatibility with package "golang.org/x/sync/errgroup" funcWithContext(ctx context.Context) (*Group, context.Context) { return &Group{done: make(chanstruct{})}, ctx }
// set max goroutine to work. func(g *Group) SetLimit(n int) { g.ch = make(chanstruct{}, n) }
// close channel only once func(g *Group) cancel() { if g.done == nil { return } g.doneOnce.Do(func() { close(g.done) }) }
// Wait blocks until all function calls from the Go method have returned, then // returns the first non-nil error (if any) from them. func(g *Group) Wait() error { g.wg.Wait() g.cancel() if g.ch != nil { close(g.ch) } return g.err }
// Go calls the given function in a new goroutine. // // The first call to return a non-nil error cancels the group; its error will be // returned by Wait. func(g *Group) Go(f func()error) { if g.ch != nil { select { case <-g.done: return case g.ch <- struct{}{}: break } }
select { case err := <-localDone: if err != nil { g.errOnce.Do(func() { g.err = err }) g.cancel() } case <-g.done: // when g.done is nil, this case will be blocked } }() }