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
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.integration.ip;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@@ -32,6 +31,8 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractInternetProtocolReceivingChannelAdapter
|
||||
@@ -56,8 +57,6 @@ public abstract class AbstractInternetProtocolReceivingChannelAdapter
|
||||
|
||||
private int poolSize = 5;
|
||||
|
||||
private volatile boolean active;
|
||||
|
||||
private volatile boolean listening;
|
||||
|
||||
|
||||
@@ -108,48 +107,6 @@ public abstract class AbstractInternetProtocolReceivingChannelAdapter
|
||||
return this.receiveBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected by lifecycleLock
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() {
|
||||
if (!this.active) {
|
||||
this.active = true;
|
||||
String beanName = this.getComponentName();
|
||||
checkTaskExecutor((beanName == null ? "" : beanName + "-") + this.getComponentType());
|
||||
this.taskExecutor.execute(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default task executor if none was supplied.
|
||||
*
|
||||
* @param threadName The thread name.
|
||||
*/
|
||||
protected void checkTaskExecutor(final String threadName) {
|
||||
if (this.active && this.taskExecutor == null) {
|
||||
Executor executor = Executors.newFixedThreadPool(this.poolSize, new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable runner) {
|
||||
Thread thread = new Thread(runner);
|
||||
thread.setName(threadName);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
this.taskExecutor = executor;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() {
|
||||
this.active = false;
|
||||
if (!this.taskExecutorSet && this.taskExecutor != null) {
|
||||
((ExecutorService) this.taskExecutor).shutdown();
|
||||
this.taskExecutor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isListening() {
|
||||
return this.listening;
|
||||
}
|
||||
@@ -197,10 +154,39 @@ public abstract class AbstractInternetProtocolReceivingChannelAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the active
|
||||
* Protected by lifecycleLock
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
@Override
|
||||
protected void doStart() {
|
||||
String beanName = getComponentName();
|
||||
checkTaskExecutor((beanName == null ? "" : beanName + "-") + getComponentType());
|
||||
this.taskExecutor.execute(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default task executor if none was supplied.
|
||||
*
|
||||
* @param threadName The thread name.
|
||||
*/
|
||||
protected void checkTaskExecutor(final String threadName) {
|
||||
if (isActive() && this.taskExecutor == null) {
|
||||
this.taskExecutor =
|
||||
Executors.newFixedThreadPool(this.poolSize,
|
||||
(runner) -> {
|
||||
Thread thread = new Thread(runner);
|
||||
thread.setName(threadName);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() {
|
||||
if (!this.taskExecutorSet && this.taskExecutor != null) {
|
||||
((ExecutorService) this.taskExecutor).shutdown();
|
||||
this.taskExecutor = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,8 +75,6 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
|
||||
|
||||
private long retryInterval = DEFAULT_RETRY_INTERVAL;
|
||||
|
||||
private volatile boolean active;
|
||||
|
||||
private volatile ClientModeConnectionManager clientModeConnectionManager;
|
||||
|
||||
private volatile ScheduledFuture<?> scheduledFuture;
|
||||
@@ -210,8 +208,7 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
|
||||
protected void onInit() {
|
||||
super.onInit();
|
||||
if (this.isClientMode) {
|
||||
Assert.notNull(this.clientConnectionFactory,
|
||||
"For client-mode, connection factory must be type='client'");
|
||||
Assert.notNull(this.clientConnectionFactory, "For client-mode, connection factory must be type='client'");
|
||||
Assert.isTrue(!this.clientConnectionFactory.isSingleUse(),
|
||||
"For client-mode, connection factory must have single-use='false'");
|
||||
}
|
||||
@@ -220,40 +217,34 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
|
||||
@Override // protected by super#lifecycleLock
|
||||
protected void doStart() {
|
||||
super.doStart();
|
||||
if (!this.active) {
|
||||
this.active = true;
|
||||
this.shuttingDown = false;
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.start();
|
||||
}
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.start();
|
||||
}
|
||||
if (this.isClientMode) {
|
||||
ClientModeConnectionManager manager =
|
||||
new ClientModeConnectionManager(this.clientConnectionFactory);
|
||||
this.clientModeConnectionManager = manager;
|
||||
Assert.state(getTaskScheduler() != null, "Client mode requires a task scheduler");
|
||||
this.scheduledFuture = getTaskScheduler().scheduleAtFixedRate(manager, this.retryInterval);
|
||||
}
|
||||
this.shuttingDown = false;
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.start();
|
||||
}
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.start();
|
||||
}
|
||||
if (this.isClientMode) {
|
||||
ClientModeConnectionManager manager =
|
||||
new ClientModeConnectionManager(this.clientConnectionFactory);
|
||||
this.clientModeConnectionManager = manager;
|
||||
Assert.state(getTaskScheduler() != null, "Client mode requires a task scheduler");
|
||||
this.scheduledFuture = getTaskScheduler().scheduleAtFixedRate(manager, this.retryInterval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // protected by super#lifecycleLock
|
||||
protected void doStop() {
|
||||
super.doStop();
|
||||
if (this.active) {
|
||||
this.active = false;
|
||||
if (this.scheduledFuture != null) {
|
||||
this.scheduledFuture.cancel(true);
|
||||
}
|
||||
this.clientModeConnectionManager = null;
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.stop();
|
||||
}
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.stop();
|
||||
}
|
||||
if (this.scheduledFuture != null) {
|
||||
this.scheduledFuture.cancel(true);
|
||||
}
|
||||
this.clientModeConnectionManager = null;
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.stop();
|
||||
}
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +292,7 @@ public class TcpInboundGateway extends MessagingGatewaySupport implements
|
||||
|
||||
@Override
|
||||
public void retryConnection() {
|
||||
if (this.active && this.isClientMode && this.clientModeConnectionManager != null) {
|
||||
if (isActive() && this.isClientMode && this.clientModeConnectionManager != null) {
|
||||
this.clientModeConnectionManager.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ import org.springframework.integration.ip.tcp.connection.ConnectionFactory;
|
||||
import org.springframework.integration.ip.tcp.connection.TcpListener;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.ErrorMessage;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -40,11 +41,13 @@ import org.springframework.util.Assert;
|
||||
* a client factory, the sender owns the connection.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
public class TcpReceivingChannelAdapter
|
||||
extends MessageProducerSupport implements TcpListener, ClientModeCapable, OrderlyShutdownCapable {
|
||||
extends MessageProducerSupport implements TcpListener, ClientModeCapable, OrderlyShutdownCapable {
|
||||
|
||||
private AbstractConnectionFactory clientConnectionFactory;
|
||||
|
||||
@@ -60,8 +63,6 @@ public class TcpReceivingChannelAdapter
|
||||
|
||||
private volatile ClientModeConnectionManager clientModeConnectionManager;
|
||||
|
||||
private volatile boolean active;
|
||||
|
||||
private volatile boolean shuttingDown;
|
||||
|
||||
private final AtomicInteger activeCount = new AtomicInteger();
|
||||
@@ -71,9 +72,7 @@ public class TcpReceivingChannelAdapter
|
||||
boolean isErrorMessage = message instanceof ErrorMessage;
|
||||
try {
|
||||
if (this.shuttingDown) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Inbound message ignored; shutting down; " + message.toString());
|
||||
}
|
||||
logger.info(() -> "Inbound message ignored; shutting down; " + message.toString());
|
||||
}
|
||||
else {
|
||||
if (isErrorMessage) {
|
||||
@@ -123,41 +122,33 @@ public class TcpReceivingChannelAdapter
|
||||
|
||||
@Override // protected by super#lifecycleLock
|
||||
protected void doStart() {
|
||||
super.doStart();
|
||||
if (!this.active) {
|
||||
this.active = true;
|
||||
this.shuttingDown = false;
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.start();
|
||||
}
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.start();
|
||||
}
|
||||
if (this.isClientMode) {
|
||||
ClientModeConnectionManager manager = new ClientModeConnectionManager(
|
||||
this.clientConnectionFactory);
|
||||
this.clientModeConnectionManager = manager;
|
||||
Assert.state(this.getTaskScheduler() != null, "Client mode requires a task scheduler");
|
||||
this.scheduledFuture = this.getTaskScheduler().scheduleAtFixedRate(manager, this.retryInterval);
|
||||
}
|
||||
this.shuttingDown = false;
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.start();
|
||||
}
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.start();
|
||||
}
|
||||
if (this.isClientMode) {
|
||||
ClientModeConnectionManager manager = new ClientModeConnectionManager(this.clientConnectionFactory);
|
||||
this.clientModeConnectionManager = manager;
|
||||
TaskScheduler taskScheduler = getTaskScheduler();
|
||||
Assert.state(taskScheduler != null, "Client mode requires a task scheduler");
|
||||
this.scheduledFuture = taskScheduler.scheduleAtFixedRate(manager, this.retryInterval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override // protected by super#lifecycleLock
|
||||
protected void doStop() {
|
||||
super.doStop();
|
||||
if (this.active) {
|
||||
this.active = false;
|
||||
if (this.scheduledFuture != null) {
|
||||
this.scheduledFuture.cancel(true);
|
||||
}
|
||||
this.clientModeConnectionManager = null;
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.stop();
|
||||
}
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.stop();
|
||||
}
|
||||
if (this.scheduledFuture != null) {
|
||||
this.scheduledFuture.cancel(true);
|
||||
}
|
||||
this.clientModeConnectionManager = null;
|
||||
if (this.clientConnectionFactory != null) {
|
||||
this.clientConnectionFactory.stop();
|
||||
}
|
||||
if (this.serverConnectionFactory != null) {
|
||||
this.serverConnectionFactory.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +156,6 @@ public class TcpReceivingChannelAdapter
|
||||
* Sets the client or server connection factory; for this (an inbound adapter), if
|
||||
* the factory is a client connection factory, the sockets are owned by a sending
|
||||
* channel adapter and this adapter is used to receive replies.
|
||||
*
|
||||
* @param connectionFactory the connectionFactory to set
|
||||
*/
|
||||
public void setConnectionFactory(AbstractConnectionFactory connectionFactory) {
|
||||
@@ -217,8 +207,7 @@ public class TcpReceivingChannelAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isClientMode
|
||||
* the isClientMode to set
|
||||
* @param isClientMode the isClientMode to set
|
||||
*/
|
||||
public void setClientMode(boolean isClientMode) {
|
||||
this.isClientMode = isClientMode;
|
||||
@@ -232,8 +221,7 @@ public class TcpReceivingChannelAdapter
|
||||
}
|
||||
|
||||
/**
|
||||
* @param retryInterval
|
||||
* the retryInterval to set
|
||||
* @param retryInterval the retryInterval to set
|
||||
*/
|
||||
public void setRetryInterval(long retryInterval) {
|
||||
this.retryInterval = retryInterval;
|
||||
@@ -251,7 +239,7 @@ public class TcpReceivingChannelAdapter
|
||||
|
||||
@Override
|
||||
public void retryConnection() {
|
||||
if (this.active && this.isClientMode && this.clientModeConnectionManager != null) {
|
||||
if (isActive() && this.isClientMode && this.clientModeConnectionManager != null) {
|
||||
this.clientModeConnectionManager.run();
|
||||
}
|
||||
}
|
||||
@@ -264,7 +252,8 @@ public class TcpReceivingChannelAdapter
|
||||
|
||||
@Override
|
||||
public int afterShutdown() {
|
||||
this.stop();
|
||||
stop();
|
||||
return this.activeCount.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user