arturobernalg opened a new pull request, #936:
URL: https://github.com/apache/httpcomponents-client/pull/936

   Implements RFC 8305 (Happy Eyeballs v2) connection racing for the Classic 
(blocking) client, as the third and final PR of this series, alongside 
apache/httpcomponents-client#935 (Async connection racing) and 
arturobernalg/httpcomponents-client#20 (Async independent A/AAAA resolution, 
stacked on #935 pending its merge). This PR is independent of the other two: 
the Classic client has its own connection path (java.net.Socket, not the 
reactor), so it needed its own, smaller mechanism rather than reusing the Async 
internals.
   
   ## Change
   
   DefaultHttpClientConnectionOperator (the Classic client's connection 
operator) can now race connection attempts across a host's resolved addresses 
instead of trying them strictly sequentially on the calling thread:
   - The first address is tried immediately, on a dedicated worker thread; each 
subsequent address is tried on its own worker thread after a configurable 
attempt delay (default 250ms, per RFC 8305 Section 8) unless an earlier attempt 
has already failed, in which case the next address is tried without further 
delay.
   - - The first attempt to connect successfully wins the race. Every other 
attempt's socket is closed: for an attempt still blocked in Socket#connect, 
closing its socket aborts that blocked call (the same mechanism java.net.Socket 
itself provides for cancelling a connect from another thread), so nothing is 
leaked; an attempt that has not yet started is prevented from ever creating a 
socket.
   - - The public, blocking connect() API is unchanged: the calling thread 
still blocks until a connection is obtained or every address has failed. The 
worker pool used for racing is created per call, bounded to the number of 
resolved addresses, and shut down before the call returns, so this adds no 
long-lived threads.
   - - TLS/ALPN negotiation happens only once, after a winning socket has been 
chosen, exactly as before this change; this PR does not touch it, or HTTP 
semantics, proxying, SOCKS, or local address binding, all of which are handled 
per attempt exactly as the existing single-attempt code already did.
   The feature is opt-in and defaults to disabled. When disabled (the default 
everywhere), the previous sequential, single-threaded behavior is preserved 
verbatim. Enabled via a new constructor overload on 
DefaultHttpClientConnectionOperator and new 
PoolingHttpClientConnectionManagerBuilder#setHappyEyeballsEnabled / 
#setConnectionAttemptDelay builder methods, mirroring the Async client's 
equivalents from #935.
   
   ## Tests
   
   New unit tests in HappyEyeballsSocketConnectorTest covering: a single 
address connecting without any racing overhead, a second address winning while 
the first is still genuinely blocked inside a (simulated) blocking connect 
call, with the loser's socket verified closed; all addresses failing with an 
aggregated IOException; a fast failure on the first address letting the second 
win without waiting out the stagger delay. The "still connecting" scenario uses 
a small Socket subclass whose connect() blocks until closed, matching the real 
behavior relied on to cancel an in-flight blocking connect.
   
   Ran: mvnw -pl httpclient5 -am test (full module) - all tests pass.
   
   ## Dependency
   
   None. Based directly on upstream master, independent of #935 and 
arturobernalg/httpcomponents-client#20.


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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to