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 ef289e3925 Review "Do not re-start already started services on
overlapping starts"
ef289e3925 is described below
commit ef289e39256918858da0eece0b10aad63d4f9fa0
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Oct 21 10:37:30 2026 +0100
Review "Do not re-start already started services on overlapping starts"
Update start state as soon as a component starts.
---
.../catalina/tribes/group/ChannelCoordinator.java | 5 +-
.../tribes/group/TestGroupChannelStartStop.java | 60 ++++++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/catalina/tribes/group/ChannelCoordinator.java
b/java/org/apache/catalina/tribes/group/ChannelCoordinator.java
index 1794441d74..89436af4cc 100644
--- a/java/org/apache/catalina/tribes/group/ChannelCoordinator.java
+++ b/java/org/apache/catalina/tribes/group/ChannelCoordinator.java
@@ -175,6 +175,7 @@ public class ChannelCoordinator extends
ChannelInterceptorBase implements Messag
clusterReceiver.setMessageListener(this);
clusterReceiver.setChannel(getChannel());
clusterReceiver.start();
+ startLevel = startLevel | Channel.SND_RX_SEQ;
// synchronize, big time FIXME
Member localMember = getChannel().getLocalMember(false);
if (localMember instanceof StaticMember) {
@@ -194,6 +195,7 @@ public class ChannelCoordinator extends
ChannelInterceptorBase implements Messag
if (Channel.SND_TX_SEQ == (toStart & Channel.SND_TX_SEQ)) {
clusterSender.setChannel(getChannel());
clusterSender.start();
+ startLevel = startLevel | Channel.SND_TX_SEQ;
valid = true;
}
@@ -204,18 +206,19 @@ public class ChannelCoordinator extends
ChannelInterceptorBase implements Messag
((McastService)
membershipService).setMessageListener(this);
}
membershipService.start(MembershipService.MBR_RX);
+ startLevel = startLevel | Channel.MBR_RX_SEQ;
valid = true;
}
if (Channel.MBR_TX_SEQ == (toStart & Channel.MBR_TX_SEQ)) {
membershipService.setChannel(getChannel());
membershipService.start(MembershipService.MBR_TX);
+ startLevel = startLevel | Channel.MBR_TX_SEQ;
valid = true;
}
if (!valid) {
throw new
IllegalArgumentException(sm.getString("channelCoordinator.invalid.startLevel"));
}
- startLevel = (startLevel | svc);
} catch (ChannelException cx) {
throw cx;
} catch (Exception e) {
diff --git
a/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
b/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
index 4460f5dc1b..cd6f2765a4 100644
--- a/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
+++ b/test/org/apache/catalina/tribes/group/TestGroupChannelStartStop.java
@@ -24,7 +24,9 @@ import org.junit.Before;
import org.junit.Test;
import org.apache.catalina.tribes.Channel;
+import org.apache.catalina.tribes.membership.McastService;
import org.apache.catalina.tribes.transport.ReceiverBase;
+import org.apache.catalina.tribes.transport.ReplicationTransmitter;
public class TestGroupChannelStartStop {
private GroupChannel channel = null;
@@ -185,6 +187,30 @@ public class TestGroupChannelStartStop {
channel.stop(Channel.DEFAULT);
}
+ @Test
+ public void testFailedStartRecordsServicesThatStarted() throws Exception {
+ CountingSender sender = new CountingSender();
+ FailingMembershipService membershipService = new
FailingMembershipService();
+ channel.setChannelSender(sender);
+ channel.setMembershipService(membershipService);
+ channel.coordinator.setChannel(channel);
+
+ int services = Channel.SND_TX_SEQ | Channel.MBR_RX_SEQ;
+ try {
+ channel.coordinator.internalStart(services);
+ Assert.fail("The first membership start should fail");
+ } catch (Exception expected) {
+ // Expected
+ }
+ Assert.assertEquals(Channel.SND_TX_SEQ,
channel.coordinator.getStartLevel());
+ Assert.assertEquals(1, sender.startCount);
+
+ channel.coordinator.internalStart(services);
+ Assert.assertEquals(services, channel.coordinator.getStartLevel());
+ Assert.assertEquals(1, sender.startCount);
+ channel.coordinator.internalStop(services);
+ }
+
@Test
public void testFalseOption() throws Exception {
int flag = 0xFFF0;//should get ignored by the underlying components
@@ -211,4 +237,38 @@ public class TestGroupChannelStartStop {
Thread.sleep(1000);
channel.stop(Channel.DEFAULT);
}
+
+ private static class CountingSender extends ReplicationTransmitter {
+
+ private volatile int startCount;
+
+ @Override
+ public synchronized void start() {
+ startCount++;
+ }
+
+ @SuppressWarnings("sync-override")
+ @Override
+ public void stop() {
+ // NO-OP
+ }
+ }
+
+ private static class FailingMembershipService extends McastService {
+
+ private boolean fail = true;
+
+ @Override
+ public void start(int level) throws Exception {
+ if (fail) {
+ fail = false;
+ throw new Exception("Test failure");
+ }
+ }
+
+ @Override
+ public void stop(int level) {
+ // NO-OP
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]