allthingssecurity opened a new pull request, #29530:
URL: https://github.com/apache/camel/pull/29530

   # Description
   
   [CAMEL-26755](https://issues.apache.org/jira/browse/CAMEL-26755)
   
   `AbstractCamelClusterService.getView` takes a reference on the view of the 
namespace, and the first reference starts the view. `ReferenceCount.retain` 
increases the count before it runs the start, and nothing gave the reference 
back when the start threw. The caller got the exception and held no reference, 
but the count stayed at 1:
   
   - the next `getView` only increased the count, so it got a view that was 
never started;
   - for a `master:` route (the consumer takes the view when it starts) started 
again by an operator or by the supervising route controller, the route was 
reported started, but the node never took part in the election, also as the 
only node and after the cause was gone;
   - a clustered route added later on the same namespace (its 
`ClusteredRoutePolicy` takes the view when the route is created) was never 
started either;
   - `releaseView` could no longer bring the count to 0, so the view was never 
stopped;
   - a stop and start of the cluster service (CamelContext restart, or the JMX 
operations) starts every view with references since CAMEL-25089, so it started 
this view that no route uses, and the node could take the leadership of a 
namespace it does not use, keeping the route of the other nodes from running.
   
   A view start fails when the backend is not reachable yet 
(`ConsulClusterView` creates a session, `JGroupsRaftClusterView` connects, 
`InfinispanRemoteClusterView` writes to the remote cache), or on an invalid 
setting (`FileLockClusterView` rejects an `acquireLockInterval` below 1 
millisecond).
   
   Change: when the start throws, the view holder gives the reference back and 
rethrows. Giving it back runs the release callback, which stops the view; a 
view whose start failed is in the `Failed` state, which `stop()` treats as 
already stopped, and a later start initializes it again. All changes of the 
count happen under the service's write lock, so nobody can take a reference in 
between. The fix is in the view holder and not in `ReferenceCount.retain`, as 
`ReferenceCount` is lock-free and an undo there is only safe when the caller 
serializes the calls, as this service does.
   
   Left as it was, for a follow-up JIRA: `ClusteredRoutePolicy` has its own 
reference count around `retainClusterView` with the same shape (it only matters 
for a policy shared by several routes; `ClusteredRoutePolicyFactory` and 
`ClusteredRouteController` create one policy per route), and `EhcacheManager` 
uses `ReferenceCount` the same way.
   
   Test, in `ClusterServiceViewTest` (in-JVM test service whose view start can 
be made to fail):
   - `testViewReferencesWhenStartFails`: the first `getView` fails; the next 
`getView` must return a started view; releasing it must stop it; a stop and 
start of the service must not start it again.
   
   On main the test fails at its second step: the second `getView` returns a 
view that is not started (status `Stopped`, its start having failed). With the 
fix: camel-core `org.apache.camel.cluster` tests 40/0 (and 50/0 together with 
`org.apache.camel.component.file.cluster`, before the test's exception check 
was tightened), camel-file cluster tests 16/0, camel-master 32/0 (it uses the 
cluster services through `MasterConsumer`), `ManagedClusterServiceTest` 1/0, 
and `ClusterServiceViewTest` (6 tests) 120/120 over 20 runs in one JVM.
   
   The reference leak is on every maintained branch; the restart symptom needs 
CAMEL-25089 (4.23.0), so a backport to `camel-4.23.x` applies as is.
   
   Found with Specula (TLA+ model checked against traces of the real code) and 
confirmed with the test above.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it): 
[CAMEL-26755](https://issues.apache.org/jira/browse/CAMEL-26755).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built the core modules with the formatter and import-sort plugins and 
ran the cluster tests of camel-core, camel-master and camel-management; no 
generated file changes. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to