Question

The RabbitMQ blog post on Publisher Confirms says

if the connection between the publisher and broker drops with outstanding confirms, it does not necessarily mean that the messages were lost, so republishing may result in duplicate messages.

This means that IModel.WaitForConfirmsOrDie() will throw an exception (just as a quick test confirmed) when the connection to the broker drops while waiting for an Ack, but the message might still get delivered. Is there a way to distinguish, by looking at the exception, whether

  1. message has definitely not been delivered
  2. message might have been delivered

In other words, is there a way to definitely distinguish all (of the potentially possible) Nacks (= not delivered) from other errors like dropped connections (after message has been accepted at the broker)?

The API docs only say

If a nack is received, throws an OperationInterruptedException exception immediately

In my 'drop connection' test, an (exception derived from) OperationInterruptedException was thrown as well, so that seems to rule out looking at the type of exception only.

Was it helpful?

Solution

Looking at the source code (.net client 3.1.3), it seems like the documentation is not quite accurate, as an IOException gets thrown in case of Nacks, a rather strange choice if you ask me:

public void WaitForConfirmsOrDie(TimeSpan timeout)
{
    bool timedOut;
    bool onlyAcksReceived = WaitForConfirms(timeout, out timedOut);
    if (!onlyAcksReceived) {
        ...
        throw new IOException("Nacks Received");
    }

Unfortunately that's just the source code, and the specification (in the api docs) differs. In any event, it looks like I could currently do this:

bool definitelyNotSend = e is IOException && "Nacks Received".Equals(e.Message);

There are, however, exceptions other than Nacks that may occur and imply the message has definitely not been sent, like when sending to an non-existing exchange. In that case, you'll get an AlreadyClosedException with a ShutdownReason.ReplyCode of 404.

Edit: My test in https://stackoverflow.com/a/18117000/709537 confirmed that the above IOException actually gets thrown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top