Errgroup Context Cancellation HTTP
Run parallel HTTP fetches under one errgroup context so the first error cancels siblings and always reclaims goroutines.
Code
package main
import (
"context"
"fmt"
"net/http"
"golang.org/x/sync/errgroup"
)
type Result struct {
URL string
Code int
}
func fetchAll(ctx context.Context, urls []string) ([]Result, error) {
g, ctx := errgroup.WithContext(ctx)
results := make([]Result, len(urls))
for i, url := range urls {
i, url := i, url // 捕获循环变量(Go 1.22 前必需)
g.Go(func() error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("build request %s: %w", url, err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("fetch %s: %w", url, err)
}
defer resp.Body.Close()
results[i] = Result{URL: url, Code: resp.StatusCode}
return nil
})
}
if err := g.Wait(); err != nil {
return nil, err // ctx 已取消,其余 goroutine 全部提前退出
}
return results, nil
}
func main() {
rs, err := fetchAll(
context.Background(),
[]string{"https://example.com/a", "https://example.com/b"},
)
fmt.Println(len(rs), err)
}Report a problem with this exampleOpens a pre-filled issue on GitHub.