allthingssecurity opened a new pull request, #29198: URL: https://github.com/apache/camel/pull/29198
# CAMEL-26573: camel-vertx-websocket - connect and disconnect consumers of a shared host one at a time https://issues.apache.org/jira/browse/CAMEL-26573 Since CAMEL-24788 the consumers on one host and port share one `VertxWebsocketHost`, which leaves the registry once it serves no consumer. `connectConsumer` gets the host (`computeIfAbsent`) and connects to it afterwards, outside the map; a `disconnectConsumer` in between sees a host that serves no consumer and removes it (`computeIfPresent`). The consumer then connects to the removed host and starts its server. Its own stop finds no host, so its path stays served after the stop and the server keeps the port until the Vert.x instance is closed; the next consumer on that host and port gets a second server on the same port. The disconnect can be the last other consumer stopping, or a consumer that fails the `sslContextParameters` check of CAMEL-26109 (its failed start stops it). Route operations hold the CamelContext lock, but `ThrottlingInflightRoutePolicy` and `ThrottlingExceptionRoutePolicy` start and stop this consumer without it. ## Changes `connectConsumer` and `disconnectConsumer` run under a lock per host and port, kept after its host goes. Other hosts and ports do not wait; consumers of one host and port already waited for each other on the host's monitor while the server starts or closes. The CAMEL-24788 comment that `computeIfPresent` made this safe is removed: it held for the two map calls, not for `host.connect`, which runs after `computeIfAbsent` returns. Why not simpler: `synchronized` methods would make every host wait for the server start or close of any other host. Connecting inside `vertxHostRegistry.compute(...)` would also work, but holds the map's bin lock while waiting for the host's monitor during a server close. ## Tests `VertxWebsocketSharedHostStartStopRaceTest` pauses one consumer after it got the host and before it connects (a host subclass), runs the other operation, and checks that nothing listens on the port once all consumers stopped: `startWhileTheLastConsumerStops` and `startWhileAnotherConsumerFailsToStart`. Both fail without the change. Found with a TLA+ model of the two operations. A stress loop without the hook (not part of this PR) left the starting consumer on a removed host in 295 of 300 runs on main and 0 of 300 with the change. No upgrade guide entry: no option or API change. Backports: `camel-4.23.x` and `camel-4.22.x` have the CAMEL-24788 code but not the CAMEL-26109 check, so a backport keeps only the first test. Follow-up, not in this PR: when the server fails to listen, `VertxWebsocketHost.start()` keeps the server that does not listen, and a consumer that connects before the failed one is stopped starts without being served. _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]
