Documentation
¶
Overview ¶
Package errgroup provides a global wait group for gracefully terminating all goroutines.
It is a custom implementation similar to sync/errgroup.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Go ¶
func Go(f func() error)
Go is a package-level helper that calls the Go method on the global instance.
Types ¶
type Group ¶
type Group interface {
// Go starts the given function either in a new goroutine or inline (if limit == 1).
Go(func() error)
// SetLimit sets the maximum number of active goroutines.
SetLimit(limit int)
// TryGo attempts to start the given function, returning true if it was started.
TryGo(func() error) bool
// Wait blocks until all tasks started with Go have completed, returning the first non-nil error (if any).
Wait() error
}
Group is a collection of goroutines working on subtasks that are part of the same overall task. A zero Group is valid; it has no limit on the number of active goroutines and does not cancel on error.
Example (JustErrors) ¶
JustErrors illustrates the use of a Group in place of a sync.WaitGroup to simplify goroutine counting and error handling. This example is derived from the sync.WaitGroup example at https://golang.org/pkg/sync/#example_WaitGroup.
package main
import (
"context"
"fmt"
"net/http"
"github.com/vdaas/vald/internal/sync/errgroup"
)
func main() {
g, _ := errgroup.New(context.Background())
urls := []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// Launch a goroutine to fetch the URL.
url := url // https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
// Fetch the URL.
resp, err := http.Get(url)
if err == nil {
resp.Body.Close()
}
return err
})
}
// Wait for all HTTP fetches to complete.
if err := g.Wait(); err == nil {
fmt.Println("Successfully fetched all URLs.")
}
}
Output:
Example (Parallel) ¶
Parallel illustrates the use of a Group for synchronizing a simple parallel task: the "Google Search 2.0" function from https://talks.golang.org/2012/concurrency.slide#46, augmented with a Context and error-handling.
package main
import (
"context"
"fmt"
"os"
"github.com/vdaas/vald/internal/sync/errgroup"
)
var (
Web = fakeSearch("web")
Image = fakeSearch("image")
Video = fakeSearch("video")
)
type (
Result string
Search func(ctx context.Context, query string) (Result, error)
)
func fakeSearch(kind string) Search {
return func(_ context.Context, query string) (Result, error) {
return Result(fmt.Sprintf("%s result for %q", kind, query)), nil
}
}
func main() {
Google := func(ctx context.Context, query string) ([]Result, error) {
g, ctx := errgroup.WithContext(ctx)
searches := []Search{Web, Image, Video}
results := make([]Result, len(searches))
for i, search := range searches {
i, search := i, search // https://golang.org/doc/faq#closures_and_goroutines
g.Go(func() error {
result, err := search(ctx, query)
if err == nil {
results[i] = result
}
return err
})
}
if err := g.Wait(); err != nil {
return nil, err
}
return results, nil
}
results, err := Google(context.Background(), "golang")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
for _, result := range results {
fmt.Println(result)
}
}
Output: web result for "golang" image result for "golang" video result for "golang"
func WithContext ¶
WithContext returns a new Group and an associated Context derived from ctx. The derived Context is canceled the first time a function passed to Go returns a non-nil error or the first time Wait returns, whichever occurs first.