This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new d3d4ac5c66 Review "Keep monitor, heartbeat and JMX alive across
partial ... stops"
d3d4ac5c66 is described below
commit d3d4ac5c66927ead10543f9ad334f7a287d62f3d
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Oct 21 11:23:25 2026 +0100
Review "Keep monitor, heartbeat and JMX alive across partial ... stops"
Clean-up TLS if all services have stopped
Keep channel on partial stop for Interceptors
---
.../tribes/group/ChannelInterceptorBase.java | 32 ++++++++++++++++++----
.../tribes/group/TestGroupChannelStartStop.java | 18 ++++++++++++
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/java/org/apache/catalina/tribes/group/ChannelInterceptorBase.java
b/java/org/apache/catalina/tribes/group/ChannelInterceptorBase.java
index c535233675..18e83ac2b7 100644
--- a/java/org/apache/catalina/tribes/group/ChannelInterceptorBase.java
+++ b/java/org/apache/catalina/tribes/group/ChannelInterceptorBase.java
@@ -187,14 +187,34 @@ public abstract class ChannelInterceptorBase implements
ChannelInterceptor {
if (getNext() != null) {
getNext().stop(svc);
}
- if (oname != null) {
- JmxRegistry jmxRegistry = JmxRegistry.getRegistry(channel);
- if (jmxRegistry != null) {
- jmxRegistry.unregisterJmx(oname);
+ // Only release the channel and the JMX registration once all services
have been stopped. A partial stop leaves
+ // services running that still use them.
+ if (isFullyStopped()) {
+ if (oname != null) {
+ JmxRegistry jmxRegistry = JmxRegistry.getRegistry(channel);
+ if (jmxRegistry != null) {
+ jmxRegistry.unregisterJmx(oname);
+ }
+ oname = null;
}
- oname = null;
+ channel = null;
}
- channel = null;
+ }
+
+ /**
+ * Determine if all services of the coordinator at the end of the
interceptor stack have been stopped.
+ *
+ * @return {@code true} if no service is started, or if there is no
coordinator after this interceptor
+ */
+ private boolean isFullyStopped() {
+ ChannelInterceptor interceptor = getNext();
+ while (interceptor != null) {
+ if (interceptor instanceof ChannelCoordinator) {
+ return ((ChannelCoordinator) interceptor).getStartLevel() == 0;
+ }
+ interceptor = interceptor.getNext();
+ }
+ return true;
}
@Override
diff --git
a/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
b/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
index cd6f2765a4..1dcf65275b 100644
--- a/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
+++ b/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
@@ -16,6 +16,7 @@
*/
package org.apache.catalina.tribes.group;
+import java.util.Iterator;
import java.util.concurrent.ScheduledFuture;
import org.junit.After;
@@ -24,6 +25,7 @@ import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.tribes.Channel;
+import org.apache.catalina.tribes.ChannelInterceptor;
import org.apache.catalina.tribes.membership.McastService;
import org.apache.catalina.tribes.transport.ReceiverBase;
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
@@ -166,6 +168,22 @@ public class TestGroupChannelStartStop {
Assert.assertTrue(heartbeat.isCancelled());
}
+ @Test
+ public void testPartialStopKeepsInterceptorChannel() throws Exception {
+ channel.start(Channel.DEFAULT);
+ channel.stop(Channel.SND_RX_SEQ);
+ // services are still running, the interceptors must still be attached
to the channel
+ for (Iterator<ChannelInterceptor> it = channel.getInterceptors();
it.hasNext();) {
+ ChannelInterceptor interceptor = it.next();
+ Assert.assertSame(interceptor.getClass().getName(), channel,
interceptor.getChannel());
+ }
+ channel.stop(Channel.SND_TX_SEQ | Channel.MBR_RX_SEQ |
Channel.MBR_TX_SEQ);
+ for (Iterator<ChannelInterceptor> it = channel.getInterceptors();
it.hasNext();) {
+ ChannelInterceptor interceptor = it.next();
+ Assert.assertNull(interceptor.getClass().getName(),
interceptor.getChannel());
+ }
+ }
+
@Test
public void testOverlappingPartialStart() throws Exception {
// start one service, then start everything: the already
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]