Tadayoshi Sato created CXF-7109:
-----------------------------------
Summary: ClientCallback may be invoked twice when Async HTTP
Transport is used
Key: CXF-7109
URL: https://issues.apache.org/jira/browse/CXF-7109
Project: CXF
Issue Type: Bug
Components: Core, Transports
Affects Versions: 3.1.8
Environment: RHEL 6.8
Reporter: Tadayoshi Sato
With Async HTTP Transport ({{cxf-rt-transports-http-hc}}) enabled, the
{{ClientCallback}} object passed for the invocation of the client may be called
twice when a failure occurs during the invocation:
{code:java}
Client client = ...
client.invoke(new ClientCallback { ... }, opName, params);
{code}
At this moment, this issue is reproduced only on RHEL 6.8, but code analysis
shows that it's a general multithreading issue with Async HTTP Transport and in
theory it can happen on any platform.
Here is what I've found with the code analysis:
If for some reason the target endpoint is not reachable, this issue can happen
when the callback for Apache HC {{HttpAsyncClient}} \[1] is invoked and thus
shuts down {{SharedOutputBuffer}} earlier than {{HTTPConduit}} tries to write
it before closing the conduit itself \[2].
\[1]
https://github.com/apache/cxf/blob/cxf-3.1.8/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduit.java#L464
\[2]
https://github.com/apache/cxf/blob/cxf-3.1.8/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/SharedOutputBuffer.java#L231
When the above issue happens, the interceptor chain's fault observer is
eventually invoked twice, once from the response workqueue thread \[3] that is
spawn by the Apache HC {{HttpAsyncClient}} callback and the second time from
the requesting thread at the interceptor chain \[4]; Thus the client callback
is also invoked twice \[5]!
\[3]
https://github.com/apache/cxf/blob/cxf-3.1.8/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java#L1177
\[4]
https://github.com/apache/cxf/blob/cxf-3.1.8/core/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java#L366
\[5]
https://github.com/apache/cxf/blob/cxf-3.1.8/core/src/main/java/org/apache/cxf/interceptor/ClientOutFaultObserver.java#L59
Why it happens so reliably only on RHEL 6.8 is still unclear (probably due to
some thread scheduling logic specific to the kernel for RHEL 6.8), but since
it's essentially an ordering issue for two distinct threads, in theory it can
happen on any platforms. In general, CXF should really enforce that every
client callback be invoked once and only once.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)