Home > Net >  golang Confusing code RabbitMq forever blocked !?
golang Confusing code RabbitMq forever blocked !?

Time:12-28

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.

  • Related