title: Quit all recursively spawned goroutines at once
body: <p>I have a function that recursively spawns goroutines to walk a DOM tree, putting the nodes they find into a channel shared between all of them.</p>
  
  <pre><code>import (
      "golang.org/x/net/html"
      "sync"
  )
  
  func walk(doc *html.Node, ch chan *html.Node) {
      var wg sync.WaitGroup
      defer close(ch)
      var f func(*html.Node)
      f = func(n *html.Node) {
          defer wg.Done()
          ch &lt;- n
          for c := n.FirstChild; c != nil; c = c.NextSibling {
              wg.Add(1)
              go f(c)
          }
      }
      wg.Add(1)
      go f(doc)
      wg.Wait()
  }
  </code></pre>
  
  <p>Which I'd call like</p>
  
  <pre><code>// get the webpage using http
  // parse the html into doc
  ch := make(chan *html.Node)
  go walk(doc, ch)
  
  for c := range ch {
      if someCondition(c) {
          // do something with c
          // quit all goroutines spawned by walk
      }
  }
  </code></pre>
  
  <p>I am wondering how I could quit all of these goroutines--i.e. close <code>ch</code>--once I have found a node of a certain type or some other condition has been fulfilled. I have tried using a <code>quit</code> channel that'd be polled before spawning the new goroutines and close <code>ch</code> if a value was received but that lead to race conditions where some goroutines tried sending on the channel that had just been closed by another one. I was pondering using a mutex but it seems inelegant and against the spirit of go to protect a channel with a mutex. Is there an idiomatic way to do this using channels? If not, is there any way at all? Any input appreciated!</p>