|
42 | 42 | import org.springframework.kafka.listener.adapter.KafkaBackoffAwareMessageListenerAdapter;
|
43 | 43 | import org.springframework.kafka.support.TopicPartitionOffset;
|
44 | 44 | import org.springframework.util.Assert;
|
45 |
| -import org.springframework.util.backoff.FixedBackOff; |
| 45 | +import org.springframework.util.backoff.BackOff; |
46 | 46 |
|
47 | 47 | /**
|
48 | 48 | *
|
@@ -81,6 +81,8 @@ public class ListenerContainerFactoryConfigurer {
|
81 | 81 |
|
82 | 82 | private static final long LOWEST_BACKOFF_THRESHOLD = 1500L;
|
83 | 83 |
|
| 84 | + private BackOff providedBlockingBackOff = null; |
| 85 | + |
84 | 86 | private Consumer<ConcurrentMessageListenerContainer<?, ?>> containerCustomizer = container -> {
|
85 | 87 | };
|
86 | 88 |
|
@@ -158,6 +160,20 @@ public KafkaListenerContainerFactory<?> decorateFactoryWithoutSettingContainerPr
|
158 | 160 | return new RetryTopicListenerContainerFactoryDecorator(factory, configuration, false);
|
159 | 161 | }
|
160 | 162 |
|
| 163 | + /** |
| 164 | + * Set a {@link BackOff} to be used with blocking retries. |
| 165 | + * You can specify the exceptions to be retried using the method |
| 166 | + * {@link org.springframework.kafka.listener.ExceptionClassifier#addRetryableExceptions(Class[])} |
| 167 | + * By default, no exceptions are retried via blocking. |
| 168 | + * @param blockingBackOff the BackOff policy to be used by blocking retries. |
| 169 | + * @since 2.8.4 |
| 170 | + * @see DefaultErrorHandler |
| 171 | + */ |
| 172 | + public void setBlockingRetriesBackOff(BackOff blockingBackOff) { |
| 173 | + Assert.notNull(blockingBackOff, "The provided BackOff cannot be null"); |
| 174 | + this.providedBlockingBackOff = blockingBackOff; |
| 175 | + } |
| 176 | + |
161 | 177 | private ConcurrentKafkaListenerContainerFactory<?, ?> doConfigure(
|
162 | 178 | ConcurrentKafkaListenerContainerFactory<?, ?> containerFactory, Configuration configuration,
|
163 | 179 | boolean isSetContainerProperties) {
|
@@ -193,14 +209,20 @@ public void setErrorHandlerCustomizer(Consumer<CommonErrorHandler> errorHandlerC
|
193 | 209 |
|
194 | 210 | protected CommonErrorHandler createErrorHandler(DeadLetterPublishingRecoverer deadLetterPublishingRecoverer,
|
195 | 211 | Configuration configuration) {
|
196 |
| - DefaultErrorHandler errorHandler = new DefaultErrorHandler(deadLetterPublishingRecoverer, |
197 |
| - new FixedBackOff(0, 0)); |
| 212 | + DefaultErrorHandler errorHandler = createDefaultErrorHandlerInstance(deadLetterPublishingRecoverer); |
| 213 | + errorHandler.defaultFalse(); |
198 | 214 | errorHandler.setCommitRecovered(true);
|
199 | 215 | errorHandler.setLogLevel(KafkaException.Level.DEBUG);
|
200 | 216 | this.errorHandlerCustomizer.accept(errorHandler);
|
201 | 217 | return errorHandler;
|
202 | 218 | }
|
203 | 219 |
|
| 220 | + protected DefaultErrorHandler createDefaultErrorHandlerInstance(DeadLetterPublishingRecoverer deadLetterPublishingRecoverer) { |
| 221 | + return this.providedBlockingBackOff != null |
| 222 | + ? new DefaultErrorHandler(deadLetterPublishingRecoverer, this.providedBlockingBackOff) |
| 223 | + : new DefaultErrorHandler(deadLetterPublishingRecoverer); |
| 224 | + } |
| 225 | + |
204 | 226 | protected void setupBackoffAwareMessageListenerAdapter(ConcurrentMessageListenerContainer<?, ?> container,
|
205 | 227 | Configuration configuration, boolean isSetContainerProperties) {
|
206 | 228 | AcknowledgingConsumerAwareMessageListener<?, ?> listener = checkAndCast(container.getContainerProperties()
|
|
0 commit comments