Search code examples
pythonrabbitmqpika

Catching exceptions within Pika callback stops callback from working


I have a callback associated with a rabbitmq queue through pika's basic_consume like so.

    channel.basic_consume(queue=REQUESTS_QUEUE,
                      on_message_callback=request_callback, auto_ack=False)

And the request callback function is:

def request_callback(channel, method, properties, body):
try:
    readings = json_util.loads(body)

    location_updater.update_location(readings)

    channel.basic_ack(delivery_tag=method.delivery_tag)
except Exception:
    logger.exception('EXCEPTION: ')

Whenever the code inside the except block is executed, this particular callback stops working (i.e. it stops being called when a message is sent to its associated queue). All the other callbacks I have associated with other queues keep working fine. If I comment out the try...except logic the callback keeps working fine for further requests, even after a exception occurs.

I'm still getting used to Python, so it might be something simple. Can anyone help?


Solution

  • I'm assuming the exception comes from a statement before channel.basic_ack, and I'm also assuming you're calling channel.basic_qos to set a prefetch value.

    The exception prevents the call to basic_ack, which prevents RabbitMQ from removing the message from the queue. If you have reached the prefetch value, no further messages will be delivered to that client because RabbitMQ assumes your client is still processing them.

    You need to decide what to do with that message when an exception happens. I'm assuming that the message can't be considered to be processed, so you should reject (nack) the message (https://www.rabbitmq.com/nack.html). Do this in the except block. This will cause the message to be re-enqueued and re-delivered, potentially to a different consumer.

    Closing the channel and/or the connection will also have the same effect. This ensures that clients that crash do not permanently "hold onto" messages.