title: How can I signal a channel sender to quit in golang?
body: <p>I'm using channels in Go to process a data pipeline of sorts. The code looks something like this:</p>
  
  <pre><code>type Channels struct {
      inputs chan string
      errc   chan error
      quit   chan struct{}
  }
  
  func (c *Channels) doSomethingWithInput() {
      defer close(c.quit)
      defer close(c.errc)
      for input := range p.inputs {
          _, err := doSomethingThatSometimesErrors(input)
          if err != nil {
              c.errc &lt;- err
              return
          }
      }
      doOneFinalThingThatCannotError()
      return
  }
  
  func (c *Channels) inputData(s string) {
          // This function implementation is my question
  }
  
  func StartProcessing(c *Channels, data ...string) error {
      go c.doSomethingWithInput()
      go func() {
          defer close(c.inputs)
          for _, i := range data {
              select {
              case &lt;-c.quit:
                  break
              default:
              }
              inputData(i)
              }
      }()
      // Block until the quit channel is closed.
      &lt;-c.quit
      if err := &lt;-c.errc; err != nil {
          return err
      }
      return nil
  }
  </code></pre>
  
  <p>This seems like a reasonable way to communicate a quit signal between channel processors and is based on <a href="http://blog.golang.org/pipelines" rel="nofollow">this blog post</a> about concurrency patterns in Go.</p>
  
  <p>The thing I struggle with using this pattern is the <code>inputData</code> function. Adding strings to the <code>input</code> channel needs to wait for <code>doSomethingWithInput()</code> to read the channel, but it also might error. <code>inputData</code> needs to try and feed the <code>inputs</code> channel but give up if told to quit. The best I could do was this:</p>
  
  <pre><code>func (c *Channels) inputData(s string) {
      for {
          select {
          case &lt;-c.quit:
              return
          case c.inputs &lt;- s:
              return
          }
      }
  }
  </code></pre>
  
  <p>Essentially, "oscillate between your options until one of them sticks." To be clear, I don't think it's a bad design. It just feels... wasteful. Like I'm missing something clever. How can I tell a channel sender to quit in Go when a channel consumer errors?</p>