Reputation: 4771
I believe I understand defer well in the normal use cases. Such as the one listed in this question Golang defer behavior. However I am a little perplexed as to what is happening when defer is called inside a goroutine that does not return. Here is the code in question.
func start_consumer() {
conn, _ := amqp.Dial("amqp://username:[email protected]")
//defer conn.Close()
ch, _ := conn.Channel()
//defer ch.Close()
q, _ := ch.QueueDeclare(
"test", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
_ = ch.Qos(
3, // prefetch count
0, // prefetch size
false, // global
)
forever := make(chan bool)
go func() {
for {
msgs, _ := ch.Consume(
q.Name, // queue
"", // consumer
false, // ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
d.Ack(true)
}
time.Sleep(1 * time.Second)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
}
This function is called from
go start_consumer()
This is likely a misunderstanding by me how channels work but I though forever would not return since it's waiting for a value to be passed to it.
Upvotes: 3
Views: 8327
Reputation: 136
The Go Blog's Defer, Panic, and Recover post referenced in the previous question does a great job explaining how defer statements work.
A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns. Defer is commonly used to simplify functions that perform various clean-up actions.
In your case since the goroutine does not return, the list of deferred calls will never be run. This makes the defer statement unnecessary in this context.
Upvotes: 7