Skip to content

Commit a862692

Browse files
authored
Executor instead of ThreadFactory for DebeziumMP
Related to #8642 For consistency with other Spring requirements and realignment with virtual threads, it is better to require a `TaskExecutor` injection instead of `ThreadFactory` * Fix `DebeziumMessageProducer` to rely on a `TaskExecutor` API instead of `ThreadFactory` and `ExecutorService` * * Remove unused import from the `DebeziumMessageProducerSpec`
1 parent b576748 commit a862692

File tree

3 files changed

+21
-47
lines changed

3 files changed

+21
-47
lines changed

spring-integration-debezium/src/main/java/org/springframework/integration/debezium/dsl/DebeziumMessageProducerSpec.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@
1818

1919
import java.util.List;
2020
import java.util.Optional;
21-
import java.util.concurrent.ThreadFactory;
2221

2322
import io.debezium.engine.ChangeEvent;
2423
import io.debezium.engine.DebeziumEngine;
2524
import io.debezium.engine.Header;
2625
import io.debezium.engine.format.SerializationFormat;
2726

27+
import org.springframework.core.task.TaskExecutor;
2828
import org.springframework.integration.debezium.inbound.DebeziumMessageProducer;
2929
import org.springframework.integration.debezium.support.DefaultDebeziumHeaderMapper;
3030
import org.springframework.integration.dsl.MessageProducerSpec;
3131
import org.springframework.messaging.support.HeaderMapper;
32-
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
3332

3433
/**
3534
* A {@link org.springframework.integration.dsl.MessageProducerSpec} for {@link DebeziumMessageProducer}.
3635
*
3736
* @author Christian Tzolov
37+
* @author Artem Bilan
3838
*
3939
* @since 6.2
4040
*/
@@ -74,19 +74,18 @@ public DebeziumMessageProducerSpec enableEmptyPayload(boolean enabled) {
7474
}
7575

7676
/**
77-
* Set a {@link ThreadFactory} for the Debezium executor. Defaults to the {@link CustomizableThreadFactory} with a
78-
* {@code debezium:inbound-channel-adapter-thread-} prefix.
79-
* @param threadFactory the {@link ThreadFactory} instance to use.
77+
* Set a {@link TaskExecutor} for the Debezium engine.
78+
* @param taskExecutor the {@link TaskExecutor} to use.
8079
* @return the spec.
8180
*/
82-
public DebeziumMessageProducerSpec threadFactory(ThreadFactory threadFactory) {
83-
this.target.setThreadFactory(threadFactory);
81+
public DebeziumMessageProducerSpec taskExecutor(TaskExecutor taskExecutor) {
82+
this.target.setTaskExecutor(taskExecutor);
8483
return this;
8584
}
8685

8786
/**
88-
* Set the outbound message content type. Must be aligned with the {@link SerializationFormat} configuration used by
89-
* the provided {@link DebeziumEngine}.
87+
* Set the outbound message content type.
88+
* Must be aligned with the {@link SerializationFormat} configuration used by the provided {@link DebeziumEngine}.
9089
* @param contentType payload content type.
9190
* @return the spec.
9291
*/

spring-integration-debezium/src/main/java/org/springframework/integration/debezium/inbound/DebeziumMessageProducer.java

+12-36
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
import java.util.Optional;
2222
import java.util.concurrent.CountDownLatch;
2323
import java.util.concurrent.Executor;
24-
import java.util.concurrent.ExecutorService;
25-
import java.util.concurrent.Executors;
26-
import java.util.concurrent.ThreadFactory;
2724
import java.util.concurrent.TimeUnit;
2825
import java.util.function.Consumer;
2926

@@ -35,14 +32,15 @@
3532
import io.debezium.engine.Header;
3633
import io.debezium.engine.format.SerializationFormat;
3734

35+
import org.springframework.core.task.SimpleAsyncTaskExecutor;
36+
import org.springframework.core.task.TaskExecutor;
3837
import org.springframework.integration.debezium.support.DebeziumHeaders;
3938
import org.springframework.integration.debezium.support.DefaultDebeziumHeaderMapper;
4039
import org.springframework.integration.endpoint.MessageProducerSupport;
4140
import org.springframework.lang.Nullable;
4241
import org.springframework.messaging.Message;
4342
import org.springframework.messaging.MessageHeaders;
4443
import org.springframework.messaging.support.HeaderMapper;
45-
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
4644
import org.springframework.util.Assert;
4745

4846
/**
@@ -60,12 +58,9 @@ public class DebeziumMessageProducer extends MessageProducerSupport {
6058
private DebeziumEngine<ChangeEvent<byte[], byte[]>> debeziumEngine;
6159

6260
/**
63-
* Debezium Engine is designed to be submitted to an {@link Executor}
64-
* or {@link ExecutorService} for execution by a single thread.
65-
* By default, a single-threaded ExecutorService instance is provided configured with a
66-
* {@link CustomizableThreadFactory} and a `debezium-` thread prefix.
61+
* Debezium Engine is designed to be submitted to an {@link Executor}.
6762
*/
68-
private ExecutorService executorService;
63+
private TaskExecutor taskExecutor;
6964

7065
private String contentType = "application/json";
7166

@@ -75,8 +70,6 @@ public class DebeziumMessageProducer extends MessageProducerSupport {
7570

7671
private boolean enableBatch = false;
7772

78-
private ThreadFactory threadFactory;
79-
8073
private volatile CountDownLatch lifecycleLatch = new CountDownLatch(0);
8174

8275
/**
@@ -116,14 +109,12 @@ public void setEnableEmptyPayload(boolean enabled) {
116109
}
117110

118111
/**
119-
* Set a {@link ThreadFactory} for the Debezium executor.
120-
* Defaults to the {@link CustomizableThreadFactory} with a
121-
* {@code debezium:inbound-channel-adapter-thread-} prefix.
122-
* @param threadFactory the {@link ThreadFactory} instance to use.
112+
* Set a {@link TaskExecutor} for the Debezium engine task.
113+
* @param taskExecutor the {@link TaskExecutor} to use.
123114
*/
124-
public void setThreadFactory(ThreadFactory threadFactory) {
125-
Assert.notNull(threadFactory, "'threadFactory' must not be null");
126-
this.threadFactory = threadFactory;
115+
public void setTaskExecutor(TaskExecutor taskExecutor) {
116+
Assert.notNull(taskExecutor, "'taskExecutor' must not be null");
117+
this.taskExecutor = taskExecutor;
127118
}
128119

129120
/**
@@ -156,12 +147,10 @@ public String getComponentType() {
156147
protected void onInit() {
157148
super.onInit();
158149

159-
if (this.threadFactory == null) {
160-
this.threadFactory = new CustomizableThreadFactory(getComponentName() + "-thread-");
150+
if (this.taskExecutor == null) {
151+
this.taskExecutor = new SimpleAsyncTaskExecutor(getComponentName() + "-thread-");
161152
}
162153

163-
this.executorService = Executors.newSingleThreadExecutor(this.threadFactory);
164-
165154
if (!this.enableBatch) {
166155
this.debeziumEngineBuilder.notifying(new StreamChangeEventConsumer<>());
167156
}
@@ -178,7 +167,7 @@ protected void doStart() {
178167
return;
179168
}
180169
this.lifecycleLatch = new CountDownLatch(1);
181-
this.executorService.execute(() -> {
170+
this.taskExecutor.execute(() -> {
182171
try {
183172
// Runs the debezium connector and deliver database changes to the registered consumer. This method
184173
// blocks until the connector is stopped.
@@ -213,19 +202,6 @@ protected void doStop() {
213202
}
214203
}
215204

216-
@Override
217-
public void destroy() {
218-
super.destroy();
219-
220-
this.executorService.shutdown();
221-
try {
222-
this.executorService.awaitTermination(5, TimeUnit.SECONDS);
223-
}
224-
catch (InterruptedException e) {
225-
throw new IllegalStateException("Debezium failed to close!", e);
226-
}
227-
}
228-
229205
@Nullable
230206
private <T> Message<?> toMessage(ChangeEvent<T, T> changeEvent) {
231207
Object key = changeEvent.key();

src/reference/asciidoc/debezium.adoc

+1-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ Defaults to `false`.
7878
- `headerMapper` - custom `HeaderMapper` implementation that allows for selecting and converting the `ChangeEvent` headers into `Message` headers.
7979
The default `DefaultDebeziumHeaderMapper` implementation provides a setter for `setHeaderNamesToMap`.
8080
By default, all headers are mapped.
81-
- `threadFactory` - Set custom `ThreadFactory` for the Debezium executor service.
82-
Debezium Engine is designed to be submitted to an `Executor` or `ExecutorService` for execution by single thread.
81+
- `taskExecutor` - Set a custom `TaskExecutor` for the Debezium engine.
8382

8483
The following code snippets demonstrate various configuration for this channel adapter:
8584

0 commit comments

Comments
 (0)