AMQ-5659: Add safety measure against infinite loop when store exception prevents message removal. Thanks to metatechbe for the patch. This fixes #72.

This commit is contained in:
Claus Ibsen 2016-11-29 18:58:17 +01:00
parent b988113587
commit 78492febc8
1 changed files with 15 additions and 0 deletions

View File

@ -1239,6 +1239,8 @@ public class Queue extends BaseDestination implements Task, UsageListener, Index
public void purge() throws Exception {
ConnectionContext c = createConnectionContext();
List<MessageReference> list = null;
long previousDequeueCount = -1;
long previousDequeueCountRepeated = 1L;
long originalMessageCount = this.destinationStatistics.getMessages().getCount();
do {
doPageIn(true, false, getMaxPageSize()); // signal no expiry processing needed.
@ -1250,6 +1252,19 @@ public class Queue extends BaseDestination implements Task, UsageListener, Index
}
for (MessageReference ref : list) {
long currentDequeueCount = this.destinationStatistics.getDequeues().getCount();
if (previousDequeueCount == currentDequeueCount) {
previousDequeueCountRepeated++;
if (previousDequeueCountRepeated >= 3) {
// Break the infinite loop in case the removal fails
// 3 times in a row -> error is fatal and not transient.
LOG.error("Aborted purge operation after attempting to delete messages failed 3 times in a row (to avoid endless looping)");
throw new RuntimeException("Purge operation failed to delete messages failed 3 times in a row (to avoid endless looping)");
}
} else {
previousDequeueCount = currentDequeueCount;
previousDequeueCountRepeated = 0L;
}
try {
QueueMessageReference r = (QueueMessageReference) ref;
removeMessage(c, r);