Skip to content

Commit b147075

Browse files
Move Task Executor logic to Timing Adjuster
1 parent 5dd5f37 commit b147075

File tree

5 files changed

+65
-67
lines changed

5 files changed

+65
-67
lines changed

spring-kafka/src/main/java/org/springframework/kafka/config/RetryTopicComponentFactory.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import org.springframework.kafka.retrytopic.SuffixingRetryTopicNamesProviderFactory;
3737

3838
/**
39-
* Provides the component instances that will be used with
39+
* Provide the component instances that will be used with
4040
* {@link RetryTopicConfigurationSupport}. Override any of the methods to provide
4141
* a different implementation or subclass, then override the
4242
* {@link RetryTopicConfigurationSupport#createComponentFactory()} method
@@ -50,7 +50,7 @@ public class RetryTopicComponentFactory {
5050
private final Clock internalRetryTopicClock = createInternalRetryTopicClock();
5151

5252
/**
53-
* Creates the {@link RetryTopicConfigurer} that will serve as an entry point
53+
* Create the {@link RetryTopicConfigurer} that will serve as an entry point
5454
* for configuring non-blocking topic-based delayed retries for a given
5555
* {@link KafkaListenerEndpoint} by processing the appropriate
5656
* {@link RetryTopicConfiguration}.
@@ -76,7 +76,7 @@ public RetryTopicConfigurer retryTopicConfigurer(DestinationTopicProcessor desti
7676
}
7777

7878
/**
79-
* Creates the {@link DestinationTopicProcessor} that will be used to process the
79+
* Create the {@link DestinationTopicProcessor} that will be used to process the
8080
* {@link DestinationTopic} instances and store them in the provided
8181
* {@link DestinationTopicResolver}.
8282
* @param destinationTopicResolver the {@link DestinationTopicResolver}
@@ -88,7 +88,7 @@ public DestinationTopicProcessor destinationTopicProcessor(DestinationTopicResol
8888
}
8989

9090
/**
91-
* Creates the instance of {@link DestinationTopicResolver} that will be used to store
91+
* Create the instance of {@link DestinationTopicResolver} that will be used to store
9292
* the {@link DestinationTopic} instances
9393
* and resolve which a given record should be forwarded to.
9494
*
@@ -99,7 +99,7 @@ public DestinationTopicResolver destinationTopicResolver() {
9999
}
100100

101101
/**
102-
* Creates a {@link DeadLetterPublishingRecovererFactory} that will be used to create
102+
* Create a {@link DeadLetterPublishingRecovererFactory} that will be used to create
103103
* the {@link DeadLetterPublishingRecoverer} that will forward the records to a given
104104
* {@link DestinationTopic}.
105105
*
@@ -113,7 +113,7 @@ public DeadLetterPublishingRecovererFactory deadLetterPublishingRecovererFactory
113113
}
114114

115115
/**
116-
* Creates the {@link ListenerContainerFactoryResolver} that will be used to resolve
116+
* Create the {@link ListenerContainerFactoryResolver} that will be used to resolve
117117
* the appropriate {@link KafkaListenerContainerFactory} for a given topic.
118118
*
119119
* @param beanFactory the {@link BeanFactory} that will be used to retrieve the
@@ -125,7 +125,7 @@ public ListenerContainerFactoryResolver listenerContainerFactoryResolver(BeanFac
125125
}
126126

127127
/**
128-
* Creates a {@link ListenerContainerFactoryConfigurer} that will be used to
128+
* Create a {@link ListenerContainerFactoryConfigurer} that will be used to
129129
* configure the {@link KafkaListenerContainerFactory} resolved by the
130130
* {@link ListenerContainerFactoryResolver}.
131131
* @param kafkaConsumerBackoffManager the {@link KafkaConsumerBackoffManager} used
@@ -143,7 +143,7 @@ public ListenerContainerFactoryConfigurer listenerContainerFactoryConfigurer(Kaf
143143
}
144144

145145
/**
146-
* Creates the {@link RetryTopicNamesProviderFactory} instance that will be used
146+
* Create the {@link RetryTopicNamesProviderFactory} instance that will be used
147147
* to provide the property names for the retry topics' {@link KafkaListenerEndpoint}.
148148
* @return the instance.
149149
*/
@@ -152,7 +152,7 @@ public RetryTopicNamesProviderFactory retryTopicNamesProviderFactory() {
152152
}
153153

154154
/**
155-
* Returns the {@link Clock} instance that will be used for all
155+
* Return the {@link Clock} instance that will be used for all
156156
* time-related operations in the retry topic processes.
157157
* @return the instance.
158158
*/
@@ -161,7 +161,7 @@ public Clock internalRetryTopicClock() {
161161
}
162162

163163
/**
164-
* Creates a {@link Clock} instance that will be used for all time-related operations
164+
* Create a {@link Clock} instance that will be used for all time-related operations
165165
* in the retry topic processes.
166166
* @return the instance.
167167
*/

spring-kafka/src/main/java/org/springframework/kafka/config/RetryTopicConfigurationSupport.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.stream.Stream;
2222

2323
import org.springframework.beans.factory.BeanFactory;
24-
import org.springframework.beans.factory.DisposableBean;
2524
import org.springframework.beans.factory.annotation.Qualifier;
2625
import org.springframework.context.ApplicationContext;
2726
import org.springframework.context.annotation.Bean;
@@ -61,12 +60,10 @@
6160
* @author Tomaz Fernandes
6261
* @since 2.9
6362
*/
64-
public class RetryTopicConfigurationSupport implements DisposableBean {
63+
public class RetryTopicConfigurationSupport {
6564

6665
private final RetryTopicComponentFactory componentFactory = createComponentFactory();
6766

68-
private DisposableBean disposableBackOffManagerFactory;
69-
7067
/**
7168
* Return a global {@link RetryTopicConfigurer} for configuring retry topics
7269
* for {@link KafkaListenerEndpoint} instances with a corresponding
@@ -272,7 +269,6 @@ public KafkaConsumerBackoffManager kafkaConsumerBackoffManager(
272269
@Qualifier(KafkaListenerConfigUtils.KAFKA_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME)
273270
ListenerContainerRegistry registry) {
274271
PartitionPausingBackOffManagerFactory factory = new PartitionPausingBackOffManagerFactory(registry);
275-
this.disposableBackOffManagerFactory = factory;
276272
return factory.create();
277273
}
278274

@@ -292,13 +288,6 @@ RetryTopicBootstrapper retryTopicBootstrapper(ApplicationContext context) {
292288
return new RetryTopicBootstrapper(context, context.getAutowireCapableBeanFactory());
293289
}
294290

295-
@Override
296-
public void destroy() throws Exception {
297-
if (this.disposableBackOffManagerFactory != null) {
298-
this.disposableBackOffManagerFactory.destroy();
299-
}
300-
}
301-
302291
public static class BlockingRetriesConfigurer {
303292

304293
private BackOff backOff;

spring-kafka/src/main/java/org/springframework/kafka/listener/PartitionPausingBackOffManagerFactory.java

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818

1919
import java.time.Clock;
2020

21-
import org.springframework.beans.factory.DisposableBean;
2221
import org.springframework.core.task.TaskExecutor;
23-
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
2422
import org.springframework.util.Assert;
2523

2624
/**
@@ -31,8 +29,7 @@
3129
* @author Tomaz Fernandes
3230
* @since 2.7
3331
*/
34-
public class PartitionPausingBackOffManagerFactory extends AbstractKafkaBackOffManagerFactory
35-
implements DisposableBean {
32+
public class PartitionPausingBackOffManagerFactory extends AbstractKafkaBackOffManagerFactory {
3633

3734
private boolean timingAdjustmentEnabled = true;
3835

@@ -150,24 +147,9 @@ private KafkaConsumerTimingAdjuster getOrCreateBackOffTimingAdjustmentManager()
150147
if (this.timingAdjustmentManager != null) {
151148
return this.timingAdjustmentManager;
152149
}
153-
return new WakingKafkaConsumerTimingAdjuster(getOrCreateTimingAdjustmentThreadExecutor());
150+
return this.taskExecutor != null
151+
? new WakingKafkaConsumerTimingAdjuster(this.taskExecutor)
152+
: new WakingKafkaConsumerTimingAdjuster();
154153
}
155154

156-
private TaskExecutor getOrCreateTimingAdjustmentThreadExecutor() {
157-
if (this.taskExecutor != null) {
158-
return this.taskExecutor;
159-
}
160-
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
161-
executor.initialize();
162-
this.taskExecutor = executor;
163-
return executor;
164-
}
165-
166-
@Override
167-
public void destroy() throws Exception {
168-
if (this.taskExecutor != null
169-
&& ThreadPoolTaskExecutor.class.isAssignableFrom(this.taskExecutor.getClass())) {
170-
((ThreadPoolTaskExecutor) this.taskExecutor).shutdown();
171-
}
172-
}
173155
}

spring-kafka/src/main/java/org/springframework/kafka/listener/PartitionPausingBackoffManager.java

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.commons.logging.LogFactory;
2525
import org.apache.kafka.common.TopicPartition;
2626

27+
import org.springframework.beans.factory.DisposableBean;
2728
import org.springframework.context.ApplicationListener;
2829
import org.springframework.core.log.LogAccessor;
2930
import org.springframework.kafka.event.ListenerContainerPartitionIdleEvent;
@@ -32,7 +33,7 @@
3233
/**
3334
*
3435
* A manager that backs off consumption for a given topic if the timestamp provided is not
35-
* due. Use with {@link SeekToCurrentErrorHandler} to guarantee that the message is read
36+
* due. Use with {@link DefaultErrorHandler} to guarantee that the message is read
3637
* again after partition consumption is resumed (or seek it manually by other means).
3738
* It's also necessary to set a {@link ContainerProperties#setIdlePartitionEventInterval(Long)}
3839
* so the Manager can resume the partition consumption.
@@ -43,10 +44,10 @@
4344
* @author Tomaz Fernandes
4445
* @author Gary Russell
4546
* @since 2.7
46-
* @see SeekToCurrentErrorHandler
47+
* @see DefaultErrorHandler
4748
*/
4849
public class PartitionPausingBackoffManager implements KafkaConsumerBackoffManager,
49-
ApplicationListener<ListenerContainerPartitionIdleEvent> {
50+
ApplicationListener<ListenerContainerPartitionIdleEvent>, DisposableBean {
5051

5152
private static final LogAccessor LOGGER = new LogAccessor(LogFactory.getLog(KafkaConsumerBackoffManager.class));
5253

@@ -75,10 +76,7 @@ public class PartitionPausingBackoffManager implements KafkaConsumerBackoffManag
7576
public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContainerRegistry,
7677
KafkaConsumerTimingAdjuster kafkaConsumerTimingAdjuster) {
7778

78-
this.listenerContainerRegistry = listenerContainerRegistry;
79-
this.kafkaConsumerTimingAdjuster = kafkaConsumerTimingAdjuster;
80-
this.clock = Clock.systemUTC();
81-
this.backOffContexts = new HashMap<>();
79+
this(listenerContainerRegistry, kafkaConsumerTimingAdjuster, Clock.systemUTC());
8280
}
8381

8482
/**
@@ -91,11 +89,7 @@ public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContaine
9189
* @param listenerContainerRegistry the listenerContainerRegistry to use.
9290
*/
9391
public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContainerRegistry) {
94-
95-
this.listenerContainerRegistry = listenerContainerRegistry;
96-
this.kafkaConsumerTimingAdjuster = null;
97-
this.clock = Clock.systemUTC();
98-
this.backOffContexts = new HashMap<>();
92+
this(listenerContainerRegistry, null, Clock.systemUTC());
9993
}
10094

10195
/**
@@ -107,7 +101,7 @@ public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContaine
107101
* @param clock the clock to use.
108102
*/
109103
public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContainerRegistry,
110-
KafkaConsumerTimingAdjuster kafkaConsumerTimingAdjuster,
104+
@Nullable KafkaConsumerTimingAdjuster kafkaConsumerTimingAdjuster,
111105
Clock clock) {
112106

113107
this.listenerContainerRegistry = listenerContainerRegistry;
@@ -124,11 +118,7 @@ public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContaine
124118
* @param clock the clock to use.
125119
*/
126120
public PartitionPausingBackoffManager(ListenerContainerRegistry listenerContainerRegistry, Clock clock) {
127-
128-
this.listenerContainerRegistry = listenerContainerRegistry;
129-
this.clock = clock;
130-
this.kafkaConsumerTimingAdjuster = null;
131-
this.backOffContexts = new HashMap<>();
121+
this(listenerContainerRegistry, null, clock);
132122
}
133123

134124
/**
@@ -229,4 +219,11 @@ protected void removeBackoff(TopicPartition topicPartition) {
229219
this.backOffContexts.remove(topicPartition);
230220
}
231221
}
222+
223+
@Override
224+
public void destroy() throws Exception {
225+
if (this.kafkaConsumerTimingAdjuster instanceof DisposableBean) {
226+
((DisposableBean) this.kafkaConsumerTimingAdjuster).destroy();
227+
}
228+
}
232229
}

spring-kafka/src/main/java/org/springframework/kafka/listener/WakingKafkaConsumerTimingAdjuster.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2021 the original author or authors.
2+
* Copyright 2018-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,9 +22,11 @@
2222
import org.apache.kafka.clients.consumer.Consumer;
2323
import org.apache.kafka.common.TopicPartition;
2424

25+
import org.springframework.beans.factory.DisposableBean;
2526
import org.springframework.core.log.LogAccessor;
2627
import org.springframework.core.task.TaskExecutor;
2728
import org.springframework.retry.backoff.Sleeper;
29+
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
2830
import org.springframework.util.Assert;
2931

3032

@@ -39,7 +41,7 @@
3941
* @since 2.7
4042
* @see KafkaConsumerBackoffManager
4143
*/
42-
public class WakingKafkaConsumerTimingAdjuster implements KafkaConsumerTimingAdjuster {
44+
public class WakingKafkaConsumerTimingAdjuster implements KafkaConsumerTimingAdjuster, DisposableBean {
4345

4446
private static final LogAccessor LOGGER =
4547
new LogAccessor(LogFactory.getLog(WakingKafkaConsumerTimingAdjuster.class));
@@ -58,17 +60,31 @@ public class WakingKafkaConsumerTimingAdjuster implements KafkaConsumerTimingAdj
5860

5961
private final Sleeper sleeper;
6062

63+
/**
64+
* Create an instance with the provided TaskExecutor and Sleeper.
65+
* @param timingAdjustmentTaskExecutor the task executor.
66+
* @param sleeper the sleeper.
67+
*/
6168
public WakingKafkaConsumerTimingAdjuster(TaskExecutor timingAdjustmentTaskExecutor, Sleeper sleeper) {
6269
Assert.notNull(timingAdjustmentTaskExecutor, "Task executor cannot be null.");
6370
Assert.notNull(sleeper, "Sleeper cannot be null.");
6471
this.timingAdjustmentTaskExecutor = timingAdjustmentTaskExecutor;
6572
this.sleeper = sleeper;
6673
}
6774

75+
/**
76+
* Create an instance with the provided TaskExecutor and a thread sleeper.
77+
* @param timingAdjustmentTaskExecutor the task executor.
78+
*/
6879
public WakingKafkaConsumerTimingAdjuster(TaskExecutor timingAdjustmentTaskExecutor) {
69-
Assert.notNull(timingAdjustmentTaskExecutor, "Task executor cannot be null.");
70-
this.timingAdjustmentTaskExecutor = timingAdjustmentTaskExecutor;
71-
this.sleeper = Thread::sleep;
80+
this(timingAdjustmentTaskExecutor, Thread::sleep);
81+
}
82+
83+
/**
84+
* Create an instance with the default TaskExecutor and a thread sleeper.
85+
*/
86+
public WakingKafkaConsumerTimingAdjuster() {
87+
this(createTaskExecutor(), Thread::sleep);
7288
}
7389

7490
/**
@@ -138,4 +154,18 @@ private void doApplyTimingAdjustment(Consumer<?, ?> consumerForTimingAdjustment,
138154
"for TopicPartition " + topicPartition);
139155
}
140156
}
157+
158+
private static TaskExecutor createTaskExecutor() {
159+
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
160+
taskExecutor.initialize();
161+
return taskExecutor;
162+
}
163+
164+
@Override
165+
public void destroy() throws Exception {
166+
if (this.timingAdjustmentTaskExecutor != null
167+
&& this.timingAdjustmentTaskExecutor instanceof ThreadPoolTaskExecutor) {
168+
((ThreadPoolTaskExecutor) this.timingAdjustmentTaskExecutor).shutdown();
169+
}
170+
}
141171
}

0 commit comments

Comments
 (0)