HTTPCLIENT-2416 - Fix pool entry leak on late lease completion#809
HTTPCLIENT-2416 - Fix pool entry leak on late lease completion#809arturobernalg wants to merge 1 commit intoapache:masterfrom
Conversation
f8fc570 to
1865484
Compare
| } catch (final TimeoutException | InterruptedException ex) { | ||
| if (!leaseFuture.cancel(true)) { | ||
| try { | ||
| final PoolEntry<HttpRoute, ManagedHttpClientConnection> latePoolEntry = leaseFuture.get( |
There was a problem hiding this comment.
@arturobernalg If the method fails once the proposed fix to call another time? That does not look right. There has to be a better fix.
There was a problem hiding this comment.
@ok2c I dropped the second get() and reworked it to use the pool.lease(..., FutureCallback) to capture late completions and release the PoolEntry on timeout/interrupt/cancel.
There was a problem hiding this comment.
@arturobernalg This hardly looks any better to me. I like @benjaminp approach better (other than the exception handling part) but I would try to push the fix into PoolingHttpClientConnectionManager or possibly even into core.
I will try to look into it on the weekend
There was a problem hiding this comment.
@ok2c Then I'll check the core and the 3 ConnPool
90770d4 to
c48f2af
Compare
|
Thanks, this does seem to resolve my examples raised on the ticket. I do have a suggested fix of my own, which is a bit less code: The idea is the check if cancelation on |
|
Close it in favor of 4b5836b |
This patch fixes a race in PoolingHttpClientConnectionManager#lease().
When LeaseRequest#get(...) exits with TimeoutException or InterruptedException, the current code calls leaseFuture.cancel(true). If the underlying lease completes just before cancellation is observed, cancel(true) returns false and the PoolEntry can remain leased, because no ConnectionEndpoint was returned to the caller and nothing releases it.
The fix handles that case in the exceptional path: if cancel(true) returns false, the code attempts a zero-timeout get() on the lease future and, if a late-completed PoolEntry is obtained, releases it immediately back to the pool.