0

I am using the Sarama library written in Go to read from an error channel when I produce a message. The overall code looks like this which is enclosed within a function:

producer.AsyncProducer.Input() <- &sarama.ProducerMessage{Topic: topic, Key: nil, Value: sarama.ByteEncoder(message)}
go func() {
    for err := range saramaProducer.Errors() {
        if producer.callbacks.OnError != nil {
            producer.callbacks.OnError(err)
        }
    }
}()

As my understanding of go routines goes, my go routine would keep iterating over the Errors() channel until it receives one. Is there a way to make it stop listening for errors once my function is done executing?

Abu Hanifa
  • 2,857
  • 2
  • 22
  • 38
Dikshant Adhikari
  • 664
  • 1
  • 10
  • 24
  • If the api expects you to range over a channel, it should close the channel when it's done. – JimB Feb 01 '18 at 15:11

1 Answers1

1

You can use another channel and a select to make the loop return.

var quit chan struct{}
go func() {
    for {
        select {
        case err:=<-saramaProducer.Errors():
            //handle errors
        case <-quit:
            return
        }
    }
}
defer func() { quit<-struct{}{} }()

The orignal for ... range loop does not iterate the channel until it gets one. Instead, it blocks until it gets an error, handle it, and waits for a new error again, until the channel close or the main returns.

There is a little problem about the above code, that owhen both quit and error channel is ready, the select picks one randomly, thus may cause a single error loss. If this is worth handling, just put another switch with default to get that error and then return.

leaf bebop
  • 7,643
  • 2
  • 17
  • 27
  • You shouldn't need to handle this case, the package will close the channel (as it should) when the producer is shutdown. – JimB Feb 01 '18 at 16:05