I'm encountering a panic: send on closed channel error in my Go application when handling AMQP messages using context timeouts. Here is a simplified version of the code that reproduces the issue:
func (i interactor) ScanExtension() (*AmqpMailSummaryModel, error) {
resultChan := make(chan AmqpMailSummaryModel)
errorChan := make(chan error)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
go func() {
defer close(resultChan)
defer close(errorChan)
err := i.services.AmqpConsumer.StartConsuming(
func(body []byte) {
/*
body to summary model
*/
resultChan <- summary
})
if err != nil {
errorChan <- fmt.Errorf("error starting consumer: %v", err)
}
}()
/*
messageBody process...
*/
err = i.services.AmqpProducer.Publish(messageBody)
if err != nil {
return nil, fmt.Errorf("failed to publish a message: %v", err)
}
select {
case result := <-resultChan:
return &result, nil
case err := <-errorChan:
return nil, err
case <-ctx.Done():
return nil, nil
}
}
func (c *RabbitMQConsumer) StartConsuming(handleMessage func(body []byte)) error {
msgs, err := c.Channel.Consume(
c.Queue,
"",
true,
false,
false,
false,
nil,
)
if err != nil {
return err
}
go func() {
for msg := range msgs {
handleMessage(msg.Body)
}
}()
return nil
}
panic: send on closed channel
goroutine 45 [running]:
tScanExtension.func1.1({0xc000782000, 0x56425a, 0x56425a})
interactor.go:306 +0x32b
(*RabbitMQConsumer).StartConsuming.func1()
Consumer.go:52 +0x1a8
created by (*RabbitMQConsumer).StartConsuming in goroutine 16
Consumer.go:48 +0x15a
exit status 2
Issue: The panic: send on closed channel error occurs when handling messages and context timeouts.
Attempts: Properly closed channels, handled context timeouts, and added logging.
Question: How can I resolve the panic: send on closed channel error? Are there additional considerations for handling channels with context timeouts in Go?
Thanks for any help!