etzel-mes opened a new pull request, #28371:
URL: https://github.com/apache/camel/pull/28371

   # Description
   
   Raised in the review of #28212 and filed as CAMEL-25912. 
`SubscriptionManager` used one lock for the subscription work and for the 
producer requests. Registering and deleting monitored items, recreating a 
subscription and the retry of refused nodes (CAMEL-25692) hold that lock across 
a blocking service call; `write`, `call`, `readValues`, `browse` and 
`getOpcUaClient()` took the same lock only to read the current connection and 
start an asynchronous request. A setpoint write therefore waited for unrelated 
subscription work on the same connection: one round trip normally, about 10 s 
during a silent network drop (until the keep-alive declared the session lost), 
up to `requestTimeout` when the server answered keep-alives but not the call. 
With one processor the outcome of a producer request also waited for the 
refused-node retry, which ran its blocking call on the single-thread 
`MiloClient` executor that completes the producer requests.
   
   What changes:
   
   - The producers and `getOpcUaClient()` read the current connection without 
the lock. `Connected.client` is final, so a request on a connection disposed 
meanwhile fails with Milo's own `UaException` (`Bad_SessionClosed`, or 
`Bad_ConnectionClosed` for one in flight) instead of a `NullPointerException`. 
`handleConnectionFailure()` and `dispose()` clear the current connection before 
they disconnect it, so `getOpcUaClient()` keeps returning `null` while there is 
no usable connection.
   - A failed producer request no longer disconnects the client and rebuilds 
the subscriptions of the consumers that share the connection. The exchange gets 
the failure (CAMEL-25694); a lost session is recovered by the client, a session 
the server no longer has fails the subscription transfer, which rebuilds the 
connection, and the watchdog (CAMEL-25691) handles a subscription that stops 
publishing. This is the decision CAMEL-25692 already took for the retry. The 
outcome is still completed on the `MiloClient` executor, so a route never 
continues on a Milo thread (CAMEL-25713).
   - The retry of refused nodes runs its attempt on the `MiloClientReconnect` 
thread instead of the `MiloClient` executor. A rebuild needs the lock, which 
the attempt holds until the server answers, so it does not wait longer than 
before.
   - Unchanged: the synchronous not-connected result with `lastConnectFailure` 
as its cause; consumer-side failures still rebuild the connection; the 
subscription work keeps the lock and its ordering.
   
   Behaviour change, documented on the component page and in the 4.24 upgrade 
guide: a failed write, call, read or browse keeps the connection (no 
`Bad_NoCommunication` report to the consumers, same session); producer requests 
and `getOpcUaClient()` no longer wait for a consumer that starts or stops or 
for the retry; while Camel rebuilds the connection a producer request fails at 
once instead of waiting for the rebuild. Two sentences of the CAMEL-25835 note 
that said a failed request rebuilds the connection are corrected. Three 
follow-ups are named in the commit message: the disconnect in 
`handleConnectionFailure()` still runs under the lock; endpoint discovery and a 
renewed server certificate are now recovered only by a Camel rebuild (as for 
consumer-only connections since CAMEL-25691); `onTransferFailed` has no 
identity check.
   
   Tests: new `ProducerOnSharedConnectionTest` (4 tests on the embedded server 
and the TCP relay, which gains `silence()`): a producer and `getOpcUaClient()` 
return within 2 s while a consumer start waits under the lock on a silent link; 
a write that times out keeps the connection; a write on a replaced connection 
fails with `Bad_ConnectionClosed` and keeps the replacement; a write completes 
within 2 s while the retry stalls on a single-thread executor. Each fails on 
the unmodified code for the stated reason. No existing assertion pinned the old 
teardown. Module `-Psourcecheck verify` with 
`-Dsurefire.rerunFailingTestsCount=0`: 125 tests, 0 failures, 1 skipped (as 
upstream).
   
   Measured on a real server (opc-plc 2.15.4 and node-opcua, client with 
`--cpus=1`, two runs each):
   
   | scenario | before | after |
   |---|---|---|
   | refused-node retry in flight, 30 s silent drop: write / read / 
`getOpcUaClient()` wait on the lock | 9–10 s / 14–15 s / 15–16 s | none |
   | the same: connection torn down after the drop | every run, one 
`Bad_NoCommunication` per consumer | none, the client reactivates the same 
session 0.1–0.9 s after the drop ends |
   | producer failure alone, 30 s drop: connection torn down | every run | 
none; writes resume 0.3–1.0 s after the drop ends (before 4.6–5.5 s) |
   | server answers keep-alives but holds CreateMonitoredItems 30 s / 70 s: 
write | 29 s / 60 s | 19–120 ms |
   
   Fixes CAMEL-25912.
   
   @davsclaus @oscerd
   
   # 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).
   
   # 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.
   
   # 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.
   
   _Claude Code on behalf of etzel-mes_
   


-- 
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