1

so im new to RabbitMQ, i have implemented a simple producer-consumer and for my use case i need to stop the consumer if the queue is empty but i can't find any solution. sender:

connection = pika.BlockingConnection(
    pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

reciver:

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245

2 Answers2

0

You can get the count of messages in queue, then exit the loop if its equal to 0.

import pika
connection = pika.BlockingConnection()
channel = connection.channel()
q = channel.queue_declare(q_name)
q_len = q.method.message_count
da Vinci
  • 131
  • 11
0

Alternatively, you could use a timeout functionality. As in, if after certain time passes by and your consumer is sitting idle, you can kill your worker/process/program.

import pika
import _thread
from threading import Timer

q_name = "hello"
conn = pika.BlockingConnection()
ch = conn.channel()
ch.queue_declare(q_name)

timeout_sec = 5 # times out in 5s


def timer():
    return Timer(timeout_sec, lambda: _thread.interrupt_main())


def callback(t, ch, method, properties, body):
    t.cancel()
    print("[x] Received:", body)
    t = timer()
    t.start()


try:
    t = timer()
    t.start()
    ch.basic_consume(
        queue=q_name,
        on_message_callback=lambda *args, **kwargs: callback(t, *args, **kwargs),
        auto_ack=True,
    )
    ch.start_consuming()
except KeyboardInterrupt:
    print("Nothing left in queue exiting....")

The above program will die if the consumer sits idle for 5 seconds.
Also note that my on_message_callback is encapsulating a regular callback that's expected by pika. That is essentially passing an instance of timer to pika's callback in order to start/stop the timer.

shriek
  • 5,605
  • 8
  • 46
  • 75