This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 81626da27948 CAMEL-26755: camel-support - AbstractCamelClusterService: 
give the view reference back when the view fails to start (#29530)
81626da27948 is described below

commit 81626da27948d5540ba7cd2acd9427fd512e23c9
Author: allthingssecurity <[email protected]>
AuthorDate: Tue Nov 10 13:28:11 2026 +0530

    CAMEL-26755: camel-support - AbstractCamelClusterService: give the view 
reference back when the view fails to start (#29530)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../camel/cluster/ClusterServiceViewTest.java      | 34 ++++++++++++++++++++++
 .../cluster/AbstractCamelClusterService.java       | 14 ++++++++-
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/cluster/ClusterServiceViewTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/cluster/ClusterServiceViewTest.java
index ea890dad9f18..08401d6ef177 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/cluster/ClusterServiceViewTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/cluster/ClusterServiceViewTest.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 
 import org.apache.camel.ServiceStatus;
@@ -94,6 +95,34 @@ public class ClusterServiceViewTest {
         assertEquals(ServiceStatus.Stopped, newView2.getStatus());
     }
 
+    @Test
+    public void testViewReferencesWhenStartFails() throws Exception {
+        TestClusterService service = new 
TestClusterService(UUID.randomUUID().toString());
+        service.start();
+
+        // the view cannot be started the first time, for example when the 
backend is not reachable yet
+        service.failedStarts.set(1);
+        Throwable failure = assertThrows(RuntimeException.class, () -> 
service.getView("ns1"));
+        while (failure != null && !(failure instanceof IllegalStateException)) 
{
+            failure = failure.getCause();
+        }
+        assertNotNull(failure, "The failure of the view start must be thrown 
to the caller");
+
+        // the next user starts the view
+        TestClusterView view = 
service.getView("ns1").unwrap(TestClusterView.class);
+        assertEquals(ServiceStatus.Started, view.getStatus());
+
+        // and the view is stopped once its only user has released it
+        service.releaseView(view);
+        assertEquals(ServiceStatus.Stopped, view.getStatus());
+
+        // a restart of the service does not start the view nobody uses
+        service.stop();
+        service.start();
+        assertEquals(ServiceStatus.Stopped, view.getStatus());
+        service.stop();
+    }
+
     @Test
     public void testViewForceOperations() throws Exception {
         TestClusterService service = new 
TestClusterService(UUID.randomUUID().toString());
@@ -212,6 +241,9 @@ public class ClusterServiceViewTest {
 
         @Override
         protected void doStart() {
+            if (((TestClusterService) 
getClusterService()).failedStarts.getAndUpdate(n -> Math.max(0, n - 1)) > 0) {
+                throw new IllegalStateException("Simulated failure to start 
view " + getNamespace());
+            }
         }
 
         @Override
@@ -232,6 +264,8 @@ public class ClusterServiceViewTest {
     }
 
     private static class TestClusterService extends 
AbstractCamelClusterService<TestClusterView> {
+        private final AtomicInteger failedStarts = new AtomicInteger();
+
         public TestClusterService(String id) {
             super(id);
         }
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/cluster/AbstractCamelClusterService.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/cluster/AbstractCamelClusterService.java
index 81b495fb0b0d..753e92236ad0 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/cluster/AbstractCamelClusterService.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/cluster/AbstractCamelClusterService.java
@@ -302,7 +302,19 @@ public abstract class AbstractCamelClusterService<T 
extends CamelClusterView> ex
         V retain() {
             LOG.debug("Retain view {}, old-refs={}", view.getNamespace(), 
count.get());
 
-            count.retain();
+            try {
+                count.retain();
+            } catch (RuntimeException e) {
+                // The view could not be started, so the caller gets no 
reference: give it back, so the next caller
+                // starts the view again instead of getting a view that is 
never started, and a restart of the
+                // service does not start a view that nobody uses.
+                try {
+                    count.release();
+                } catch (RuntimeException e2) {
+                    e.addSuppressed(e2);
+                }
+                throw e;
+            }
 
             return get();
         }

Reply via email to