Serdar Gökay created CAMEL-25912:
------------------------------------
Summary: camel-milo - client producers wait for the manager lock
while a subscription service call holds it
Key: CAMEL-25912
URL: https://issues.apache.org/jira/browse/CAMEL-25912
Project: Camel
Issue Type: Improvement
Components: camel-milo
Reporter: Serdar Gökay
h3. Problem
{{SubscriptionManager}} uses one {{lock}} for the subscription work and for the
producer requests. Registering monitored items, deactivating them when a route
stops, recreating a subscription and, with CAMEL-25692, creating refused items
again all hold {{lock}} across a blocking service call. The producer methods
{{write}}, {{call}}, {{readValues}} and {{browse}}, and {{getOpcUaClient()}},
take the same {{lock}}, although under it they only read the current connection
and start an asynchronous request. A producer request therefore waits, with its
thread blocked, until the service call that holds {{lock}} completes:
* normally one round trip;
* during a silent network drop, until the keep-alive notices it. Against a real
server with a refused node, a {{getOpcUaClient()}} call waited 9.8 s (see the
review of [#28212|https://github.com/apache/camel/pull/28212]);
* with a server that answers the keep-alives but not the service call, up to
the request timeout (60 s by default).
A write that sets a setpoint or sends a command then waits for unrelated
subscription work on the same connection, for example another route that starts
or stops.
h3. Proposal
The producer methods and {{getOpcUaClient()}} read the current connection
without {{lock}} (a volatile field, still written under {{lock}}) and start
their request as today. The subscription work keeps {{lock}}. Two things have
to hold then:
# {{Connected.dispose()}} sets {{client}} to null. A request on a connection
that is disposed meanwhile has to complete exceptionally, not with a
NullPointerException.
# A failed request calls {{handleConnectionFailure}}, which tears down whatever
connection is current. Without {{lock}} the failure may come from a connection
that was replaced meanwhile, so it has to tear down only the connection the
request was sent on.
For the second point it is worth deciding first whether a failed request should
tear the connection down at all: Milo reactivates a lost session itself, and
since CAMEL-25835 the consumers are told about the loss. If it should not, the
second point goes away.
h3. Related
CAMEL-25694 and CAMEL-25695
([#27956|https://github.com/apache/camel/pull/27956]) change the completion of
the same four producer methods from {{handleAsync}} to {{whenCompleteAsync}};
this change would follow that one. Raised in the review of CAMEL-25692
([#28212|https://github.com/apache/camel/pull/28212]).
I can send a PR.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)