[
https://issues.apache.org/jira/browse/HTTPCORE-584?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16894152#comment-16894152
]
Linton Miller edited comment on HTTPCORE-584 at 7/26/19 10:21 PM:
------------------------------------------------------------------
On review, removing isn't the cheapest of operations, so preferable to only do
it if we have to. Also, there's no good way to maintain the PoolReuse ordering.
Instead, I tried out just using a marker on each entry in the queue as to
whether it's "committed" or not; only uncommitted entries can be returned from
lease. Then iteration just temporarily marks each entry in the queue as
committed while it's being processed. This does mean that multiple iterators
running at once may see a random subset of all available entries, but that
seems acceptable to me.
Making the change meant I also found what I think is a separate issue, that a
pending lease request might get lost and never completed or failed. I fixed
that in my changes too, but not sure if you'd like to track that as a separate
issue?
All my changes can be reviewed in
[https://github.com/apache/httpcomponents-core/pull/132]
Linton
P.S. New Zealand is a country down the bottom of the world near Australia,
small enough that we get left off all sorts of maps ;)
[https://www.youtube.com/watch?v=T2_yF0TxqOw]
was (Author: linton.miller):
On review, removing isn't the cheapest of operations, so preferable to only do
it if we have to. Also, there's no good way to maintain the PoolReuse ordering.
Instead, I tried out just using a marker on each entry in the queue as to
whether it's "committed" or not; only uncommitted entries can be returned from
lease. Then iteration just temporarily marks each entry in the queue as
committed which it's being processed. This does mean that multiple iterators
running at once may see a random subset of all available entries, but that
seems acceptable to me.
Making the change meant I also found what I think is a separate issue, that a
pending lease request might get lost and never completed or failed. I fixed
that in my changes too, but not sure if you'd like to track that as a separate
issue?
All my changes can be reviewed in
[https://github.com/apache/httpcomponents-core/pull/132]
Linton
P.S. New Zealand is a country down the bottom of the world near Australia,
small enough that we get left off all sorts of maps ;)
https://www.youtube.com/watch?v=T2_yF0TxqOw
> Iterating a LaxConnPool is not thread-safe
> ------------------------------------------
>
> Key: HTTPCORE-584
> URL: https://issues.apache.org/jira/browse/HTTPCORE-584
> Project: HttpComponents HttpCore
> Issue Type: Bug
> Components: HttpCore
> Affects Versions: 5.0-beta8
> Reporter: Linton Miller
> Priority: Major
> Fix For: 5.0-beta9
>
> Attachments: LaxConnPoolThreadingTest.java,
> LaxConnPoolThreadingTest2.java
>
>
> Iterating over connections in a LaxConnPool can cause unexpected connection
> exceptions; for example, calling the closeIdle or closeExpired methods at the
> same time as threads are requesting connections from the pool.
> This is demonstrated by the attached test class, which creates a LaxConnPool
> for a PoolingHttpClientConnectionManager and then uses that to execute a
> number of concurrent requests, sleeps a bit, then re-executes concurrent
> requests at the same time as closing idle connections in the pool. Being a
> threading bug, it's not a guaranteed fail every time, but within a few runs,
> the test code will normally get at least one request thread that fails. e.g
> {noformat}
> Thread req-000000AB request failed!
> org.apache.hc.core5.http.ConnectionClosedException: Connection is closed
> at
> org.apache.hc.core5.http.impl.io.BHttpConnectionBase.ensureOpen(BHttpConnectionBase.java:98)
> at
> org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:186)
> at
> org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:181)
> at
> org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:224)
> at
> org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:596)
> at
> org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:220)
> at
> org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:175)
> ...
> at
> org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:77)
> at
> org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:102)
> at
> LaxConnPoolThreadingTest$2.executeReq(LaxConnPoolThreadingTest.java:69)
> at
> LaxConnPoolThreadingTest$2.run(LaxConnPoolThreadingTest.java:58){noformat}
> or
>
> {noformat}
> Thread req-00000179 request failed!
> java.lang.IllegalStateException: Endpoint is not connected
> at org.apache.hc.core5.util.Asserts.check(Asserts.java:38)
> at
> org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.getValidatedPoolEntry(PoolingHttpClientConnectionManager.java:548)
> at
> org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:592)
> ...{noformat}
> There may also be recoverable I/O exceptions logged:
> {noformat}
> 2019-07-24 09:17:27,488 INFO
> [org.apache.hc.client5.http.impl.classic.RetryExec] Recoverable I/O exception
> (java.net.SocketException) caught when processing request to
> {}->http://httpbin.org:80{noformat}
>
> This appear to be because the iteration methods of LaxConnPool are not
> thread-safe. Though their access to the internal queue structures are
> protected by the queues being ConcurrentLinkedDeque, the iteration provides
> the means for the same pool entry to be accessed on multiple threads at once
> because there is no locking or concurrency control on the individual pool
> entries as the callback is executed through enumAvailable or enumLeased.
>
>
>
--
This message was sent by Atlassian JIRA
(v7.6.14#76016)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]