Rely on MProducerSupport.active for Flux (#3423)
* Rely on `MProducerSupport.active` for `Flux` * Fix `MessageProducerSupport` to extract an `active` flag and set it before `isRunning` - the `Flux` subscription relies on the `takeWhile()` where in case of `autoStartup = false` we will never start consume because it is set to `true` already after `doStart()` * Refactor all the `MessageProducerSupport` implementation with similar `active` state to use already one from the super class **Cherry-pick to 5.3.x** * * Remove `MessageProducerSupport.setActive()` to not let to mutate it from the implementations * Set `active` to `false` in the `destroy()` * Clean up and fix typos in the affected `JmsMessageDrivenEndpoint` * * Pull `active` flag down to the `AbstractEndpoint` * Set `active = true` in the `start()` before calling `doStart()` * Do same for `active = false` in the `stop()` * Clean up `AbstractEndpoint` impls to not call `doStart/doStop` for nothing * Refactor endpoints to rely on the `active` state from the `AbstractEndpoint` not their own
This commit is contained in:
committed by
Gary Russell
parent
27b464ad27
commit
002382e647
@@ -47,14 +47,6 @@ import org.springframework.util.StringUtils;
|
||||
public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
implements SmartLifecycle, DisposableBean {
|
||||
|
||||
private boolean autoStartupSetExplicitly;
|
||||
|
||||
private volatile boolean autoStartup = true;
|
||||
|
||||
private volatile int phase = 0;
|
||||
|
||||
private volatile boolean running;
|
||||
|
||||
protected final ReentrantLock lifecycleLock = new ReentrantLock(); // NOSONAR
|
||||
|
||||
protected final Condition lifecycleCondition = this.lifecycleLock.newCondition(); // NOSONAR
|
||||
@@ -63,6 +55,16 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
|
||||
private SmartLifecycleRoleController roleController;
|
||||
|
||||
private boolean autoStartup = true;
|
||||
|
||||
private boolean autoStartupSetExplicitly;
|
||||
|
||||
private int phase = 0;
|
||||
|
||||
private volatile boolean running;
|
||||
|
||||
private volatile boolean active;
|
||||
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
this.autoStartup = autoStartup;
|
||||
this.autoStartupSetExplicitly = true;
|
||||
@@ -120,6 +122,7 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
stop();
|
||||
if (this.roleController != null) {
|
||||
this.roleController.removeLifecycle(this);
|
||||
}
|
||||
@@ -153,6 +156,7 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
this.lifecycleLock.lock();
|
||||
try {
|
||||
if (!this.running) {
|
||||
this.active = true;
|
||||
doStart();
|
||||
this.running = true;
|
||||
if (logger.isInfoEnabled()) {
|
||||
@@ -170,6 +174,7 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
this.lifecycleLock.lock();
|
||||
try {
|
||||
if (this.running) {
|
||||
this.active = false;
|
||||
doStop();
|
||||
this.running = false;
|
||||
if (logger.isInfoEnabled()) {
|
||||
@@ -187,6 +192,7 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
this.lifecycleLock.lock();
|
||||
try {
|
||||
if (this.running) {
|
||||
this.active = false;
|
||||
doStop(callback);
|
||||
this.running = false;
|
||||
if (logger.isInfoEnabled()) {
|
||||
@@ -211,6 +217,10 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport
|
||||
callback.run();
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method with the start behavior.
|
||||
* This method will be invoked while holding the {@link #lifecycleLock}.
|
||||
|
||||
@@ -368,7 +368,7 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
triggerContext.lastActualExecutionTime(),
|
||||
new Date())
|
||||
)), 1)
|
||||
.repeat(this::isRunning)
|
||||
.repeat(this::isActive)
|
||||
.doOnSubscribe(subs -> this.subscription = subs);
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ public abstract class MessageProducerSupport extends AbstractEndpoint implements
|
||||
.map(this::trackMessageIfAny)
|
||||
.doOnComplete(this::stop)
|
||||
.doOnCancel(this::stop)
|
||||
.takeWhile((message) -> isRunning());
|
||||
.takeWhile((message) -> isActive());
|
||||
|
||||
if (channelForSubscription instanceof ReactiveStreamsSubscribableChannel) {
|
||||
((ReactiveStreamsSubscribableChannel) channelForSubscription).subscribeTo(messageFlux);
|
||||
|
||||
@@ -1016,6 +1016,12 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
this.gatewayMap.values().forEach(MethodInvocationGateway::destroy);
|
||||
}
|
||||
|
||||
private static final class MethodInvocationGateway extends MessagingGatewaySupport {
|
||||
|
||||
private Expression receiveTimeoutExpression;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.integration.endpoint;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -50,17 +50,18 @@ public class ReactiveMessageProducerTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(this.producer.isRunning()).isTrue();
|
||||
StepVerifier stepVerifier =
|
||||
StepVerifier.create(
|
||||
Flux.from(this.fluxMessageChannel)
|
||||
.map(Message::getPayload)
|
||||
.cast(String.class))
|
||||
.expectNext("test1", "test2")
|
||||
.thenCancel()
|
||||
.verifyLater();
|
||||
|
||||
StepVerifier.create(
|
||||
Flux.from(this.fluxMessageChannel)
|
||||
.map(Message::getPayload)
|
||||
.cast(String.class))
|
||||
.expectNext("test1", "test2")
|
||||
.thenCancel()
|
||||
.verify();
|
||||
this.producer.start();
|
||||
|
||||
assertThat(this.producer.isRunning()).isFalse();
|
||||
stepVerifier.verify(Duration.ofSeconds(10));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -79,10 +80,12 @@ public class ReactiveMessageProducerTests {
|
||||
|
||||
@Override
|
||||
protected void doStart() {
|
||||
super.doStart();
|
||||
subscribeToPublisher(Flux.just("test1", "test2").map(GenericMessage::new));
|
||||
}
|
||||
|
||||
};
|
||||
producer.setAutoStartup(false);
|
||||
producer.setOutputChannel(fluxMessageChannel());
|
||||
return producer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user