I found an interesting piece of code when using rabbitMQ
forever := make(chan bool)
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL C")
<-forever
This is a block of code , In fact, in normal mode, this would cause a deadlock error, Like this enter image description here enter image description here
But when I import rabbitMQ package , this code does not cause an error enter image description here Why is that? I'm confused. Thanks for answer!
Expect someone to explain
CodePudding user response:
When you are using rabbitmq, the msgs
variable is a receiving channel of type <-chan amqp.Delivery
- see docs i.e a channel receive messages. The range loop is enters the body each time a message appears. This is a useful control sequence - block the main goroutine whilst the worker awaits and processes messages. There is no deadlock in this case as rabbitmq connection will send messages down the msgs
chan when appropriate.
In earlier code, when you connect to the queue and instantiate the msgs
channel, the amqp package çreates another goroutine in the background to send messages down the msgs
channel.
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
This is unlike the deadlock examples provided, where there is no additional go-routines to send messages down the forever
channel. The goroutine goes to sleep and there is no chance of it being awakened. It is a deadlock.