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]

Reply via email to