What is the proper way to read from the errors channel in Sarama?

Issue

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?

Solution

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.

Answered By – leaf bebop

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.