title: Idiomatic goroutine termination and error handling
body: <p>I have a simple concurrency use case in go, and I cannot figure out an elegant solution to my problem.</p>
  <p>I want to write a method <code>fetchAll</code> that queries an unspecified number of resources from remote servers in parallel. If any of the fetches fails, I want to return that first error immediately.</p>
  <p>My initial implementation leaks goroutines:</p>
  <pre class="lang-golang prettyprint-override"><code>    package main
  
      import (
        &quot;fmt&quot;
        &quot;math/rand&quot;
        &quot;sync&quot;
        &quot;time&quot;
      )
  
      func fetchAll() error {
        wg := sync.WaitGroup{}
        errs := make(chan error)
        leaks := make(map[int]struct{})
        defer fmt.Println(&quot;these goroutines leaked:&quot;, leaks)
  
        // run all the http requests in parallel
        for i := 0; i &lt; 4; i++ {
          leaks[i] = struct{}{}
          wg.Add(1)
          go func(i int) {
            defer wg.Done()
            defer delete(leaks, i)
  
            // pretend this does an http request and returns an error
            time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
            errs &lt;- fmt.Errorf(&quot;goroutine %d's error returned&quot;, i)
          }(i)
        }
  
        // wait until all the fetches are done and close the error
        // channel so the loop below terminates
        go func() {
          wg.Wait()
          close(errs)
        }()
  
        // return the first error
        for err := range errs {
          if err != nil {
            return err
          }
        }
  
        return nil
      }
  
      func main() {
        fmt.Println(fetchAll())
      }
  </code></pre>
  <p>Playground: <a href="https://play.golang.org/p/Be93J514R5" rel="noreferrer">https://play.golang.org/p/Be93J514R5</a></p>
  <p>I know from reading <a href="https://blog.golang.org/pipelines" rel="noreferrer">https://blog.golang.org/pipelines</a> that I can create a signal channel to cleanup the other threads. Alternatively, I could probably use <code>context</code> to accomplish it. But it seems like such a simple use case should have a simpler solution that I'm missing.</p>