Search code examples
rabbitmqamqp

RabbitMQ: does basic_ack also needs to be confirmed by the server?


Say I put a channel in confirmation mode with "confirm.select", and the ack mode is set to manual, then I do the following (pseudo code):

function msg_handler(msg: TheDelivery, chan: TheChannelThatDeliverredThisMessage) {
    let new_msg = do_some_computation(msg)

    let confirm = chan.basic_publish(some_other_queue, new_msg)

    -- wait for rabbitmq to confirm this new_msg
    confirm.wait_for_rmq_confirmation()
    
    let x = chan.basic_ack(msg.delivery_tag)

    -- Question: do I need x.wait_for_rmq_confirmation() here?
    -- namely, does the basic_ack/reject/nack needs to be confirmed 
    -- if the channel is in confirmation mode?

    -- The library I am using doesn't require the ack to be confirmed,
    -- for the basic_ack call returns unit, so there is no handle to wait on,
    -- I just want to know that this is the way the AMQP designed (no confirms
    -- of the ack are generated by the rmq server), or that, the protocol requires
    -- that the confirmation of the channel.basic_ack should be generated by the server,
    -- it's just that the library I am using that hides this from me (when the channel is
    -- in confirmation mode)
}

channel.basic_consume(some_queue_name, msg_handler).wait_forever()

Solution

  • No, basic.ack does not need to be confirmed. If something happens to the acknowledgement message (it is lost on the network, for instance), RabbitMQ will keep the message in the "Unacked" state. When the channel associated with that message is closed, RabbitMQ will re-enqueue it and will deliver it to the next consumer of that queue.

    Note that this means the message will be delivered twice! This is a case (rare, but possible) you must take into account.