fix: do not reattempt connecting if there are no available addresses

usually, a connection connects when there are available IPs to try.
in a persistent connection scenario, the same holds. however, in a
fiber-based environment, fiber 1 may wait for request 1, while fiber 2
may, while attempting request 2, receive a GOAWAY frame, and initiate
termination/reconnection/resend while switching on the DNS request
phase,
whereas when the context is switched back to fiber 1, request 1 has
already
failed due to what happened in fiber 2 and should be reattempted,
however the
connection is still waiting on the DNS answer, so the reattempt should
just be enqueued.

This fixes by relying on the assumption that an idle connection with no
addresses in the select loop is a connection that has been sent back to
the name resolution loop, so the flow needs to ignore it and go back to
the request handling loop, which will forward the request-to-retry and
wait on the same resolution.
This commit is contained in:
HoneyryderChuck 2025-09-18 09:52:25 +01:00
parent bbd4a59892
commit e7699950b2

View File

@ -82,6 +82,17 @@ module HTTPX
def connect
return unless closed?
if @addresses.empty?
# an idle connection trying to connect with no available addresses is a connection
# out of the initial context which is back to the DNS resolution loop. This may
# happen in a fiber-aware context where a connection reconnects with expired addresses,
# and context is passed back to a fiber on the same connection while waiting for the
# DNS answer.
log { "tried connecting while resolving, skipping..." }
return
end
if !@io || @io.closed?
transition(:idle)
@io = build_socket