Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,15 @@ public void handleDeliveryToTargetQueueAck(final long deliveryTag, final boolean
deliveryTag, true
);

LOGGER.trace("Ack (multiple) message source delivery {} from {} after publish confirm {} of message to {}",
LOGGER.debug("Ack (multiple) message source delivery {} from {} after publish confirm {} of message to {}",
confirmed.lastKey(), stagingQueue.getName(), outstandingConfirms.get(deliveryTag),
targetQueue.getName());

stagingQueueChannel.basicAck(confirmed.lastKey(), true);
confirmed.clear();
timeSinceLastDoneWork = Instant.now();
} else {
LOGGER.trace("Ack message source delivery {} from {} after publish confirm {} of message to {}",
LOGGER.debug("Ack message source delivery {} from {} after publish confirm {} of message to {}",
outstandingConfirms.get(deliveryTag), stagingQueue.getName(), outstandingConfirms.get(deliveryTag),
targetQueue.getName());

Expand Down Expand Up @@ -259,10 +259,17 @@ public void handleDeliveryToTargetQueueNack(final long deliveryTag, final boolea
final ConcurrentNavigableMap<Long, Long> confirmed = outstandingConfirms.headMap(
deliveryTag, true
);

for(final Long messageDeliveryTagToNack: confirmed.values()) {
stagingQueueChannel.basicNack(messageDeliveryTagToNack, true, true);
}
LOGGER.debug("Nack (multiple) message source delivery {} from {} after publish confirm {} of message to {}",
confirmed.lastKey(), stagingQueue.getName(), outstandingConfirms.get(deliveryTag),
targetQueue.getName());

/// Using stagingQueueChannel.basicNack(confirmed.lastKey(), true, true); is preferred over looping and nacking each message individually because:
/// Efficiency: The multiple=true flag tells RabbitMQ to nack all messages up to and including lastKey in a single network call, reducing protocol overhead and improving performance.
/// Atomicity: It ensures all relevant messages are nacked together, avoiding race conditions or partial failures that could occur if nacking in a loop.
/// Simplicity: The code is simpler, easier to read, and less error-prone than managing a loop and multiple nack calls.
/// Consistency: This approach matches the semantics of how RabbitMQ delivers multiple acks/nacks, ensuring message order and state are handled as expected.
/// In summary, using the multiple flag with a single nack is more efficient, reliable, and idiomatic for RabbitMQ.
stagingQueueChannel.basicNack(confirmed.lastKey(), true, true);

confirmed.clear();
} else {
Expand Down