From bb45fb4538d723ecdc136ceaaba032bcf8cdb42c Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 29 Sep 2014 15:35:07 +0200 Subject: [PATCH] Restore sleep interval between recovery attempt Commit 6a04831 introduced a regression that lead to burst recovery attempts when the broker is up but the listener is failing for some reason (the most obvious one being that the destination does not exist). Since the sleep period between recovery attempts strategy is more complex, we can't just sleep for a period of time. But we can create an execution and apply it once which should work just fine for most use cases. Issue: SPR-12183 --- .../DefaultMessageListenerContainer.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java index 7eb1d28610e..9bd050a3fed 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/DefaultMessageListenerContainer.java @@ -1040,6 +1040,11 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe } catch (Throwable ex) { clearResources(); + if (!this.lastMessageSucceeded) { + // We failed more than once in a row or on startup - sleep before + // first recovery attempt. + sleepBeforeRecoveryAttempt(); + } this.lastMessageSucceeded = false; boolean alreadyRecovered = false; synchronized (recoveryMonitor) { @@ -1191,6 +1196,17 @@ public class DefaultMessageListenerContainer extends AbstractPollingMessageListe this.session = null; } + /** + * Apply the back off time once. In a regular scenario, the back off is only applied if we + * failed to recover with the broker. This additional sleep period avoids a burst retry + * scenario when the broker is actually up but something else if failing (i.e. listener + * specific). + */ + private void sleepBeforeRecoveryAttempt() { + BackOffExecution execution = DefaultMessageListenerContainer.this.backOff.start(); + applyBackOffTime(execution); + } + @Override public boolean isLongLived() { return (maxMessagesPerTask < 0);