Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does pika confirm_delivery mean confirm when broker got the message or when consumer acknowledged?

From my producer code I want to know when the consumer has basic.acked a message.

Using channel.confirm_delivery() and a BlockingConnection it is not clear from the documentation if this should confirm 1) the broker having received the message, or, 2) a consumer having acknowledge receiving it.

Running this code (with no consumer):

import pika
import uuid

# Open a connection to RabbitMQ on localhost using all default parameters
connection = pika.BlockingConnection()
# Open the channel
channel = connection.channel()
queue = str(uuid.uuid4())

# Declare the queue
channel.queue_declare(queue=queue)

# Turn on delivery confirmations
channel.confirm_delivery()

# Send a message
if channel.basic_publish(exchange='',
                         routing_key=queue,
                         body='Hello World!',
                         properties=pika.BasicProperties(
                             content_type='text/plain',
                             delivery_mode=1)):
    print('Message publish was confirmed')
else:
    print('Message could not be confirmed')

shows the message to be confirmed. This is not what I expect or want.

This may be a duplicate of Behavior of channels in "confirm" mode with RabbitMQ however the documentation for basic_publish says

:returns: True if delivery confirmation is not enabled (NEW in pika 0.10.0); otherwise returns False if the message could not be deliveved (Basic.nack and/or Basic.Return) and True if the message was delivered (Basic.ack and no Basic.Return)

which makes me think it should have the I wanted in the first place.

like image 252
Martin Avatar asked Mar 15 '17 14:03

Martin


1 Answers

confirm_deliveries just means that when RabbitMQ has received a message, either a basic.ack (message received) or basic.nack (message not received) will be returned.

This does however not guarantee that the message was successfully delivered to a queue. You will need to add the mandatory flag for an unroutable message to throw an exception.

You can read more about confirm deliveries and the mandatory flag here.

Answering your question; there is no way for the publisher to know if a consumer successfully handled the message. However, if a consumer fails to consume a message, it should be re-queued and handle by another consumer, but that depends on how well the consumers were designed.

If you really need to know if a message has been handled properly, implementing something like an RPC call that replies back with the status of the request may be the best approach. If you don't get a response within X seconds, assume that the message wasn't handled. https://www.rabbitmq.com/tutorials/tutorial-six-python.html

If you need a async example for rpc publishers you can take a look at some of my examples for flask here.

like image 86
eandersson Avatar answered Nov 05 '22 12:11

eandersson