lore-transport: Happy eyeballs strategy for QUIC fallback connections across resolved addresses#28
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the QUIC client connection logic to use a Happy Eyeballs-style strategy when a hostname resolves to multiple socket addresses, avoiding long stalls on an unreachable first address while preserving existing per-address configuration and error behavior.
Changes:
- Collect resolved socket addresses and attempt connections concurrently with a fixed stagger (250ms).
- Introduce
connect_happy_eyeballsto schedule attempts and return the first successful connection. - Add unit tests covering stalled-first-attempt fallback, immediate advance on failure, no fallback after first success, and all-fail behavior.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ragnarula
left a comment
There was a problem hiding this comment.
This is neat! I wasn't aware of the happy eyeballs technique before. Left some minor comments to address.
e8bbffe to
fe91bcf
Compare
|
This looks like a pretty good addition now! However, please remove the additional |
|
@mjansson Ok, I removed the unnecessary attribution, should I now squash the commits, or you'll do it on your end? |
Doesn't matter, but all the commits need to be with the DCO sign-off - the |
ee2c100 to
f457a07
Compare
|
@mjansson Done, one commit, signed-off as per DCO. |
f457a07 to
c85f9c1
Compare
Signed-off-by: Andrzej Haczewski <ahaczewski@gmail.com>
c85f9c1 to
c552b7b
Compare
Use a Happy Eyeballs strategy (see RFC8305) when the QUIC client connects
to a hostname that resolves to multiple socket addresses.
The client now:
The existing per-address endpoint setup and final error behavior remain unchanged.
Why
The previous implementation awaited QUIC addresses sequentially. If
localhostresolved to::1before127.0.0.1whileloreserverlistened onits default IPv4 address, the IPv6 attempt consumed the full 30-second QUIC idle
timeout before IPv4 was attempted.
This caused commands such as
lore historyto take about 30seconds because repository initialization had started a background QUIC
pre-warm, even if not required.
Before:
Using
127.0.0.1directly completed in0.08s, confirming that addressfallback was responsible for the delay.
Closes #27
Testing
Added unit coverage for:
Verification performed:
All 28
lore-transporttests pass.The original reproduction using
lore://localhost:41337now completes in:A remote immutable-store query also demonstrated the complete fallback:
Note on tests
The
lore-transport/src/quic/client.rsfile did not contain any test previously,and if they are wrongly placed, let me know and I'll make amendments.
Alternative approach
The alternative would be to prevent QUIC from connecting for commands
that do not require QUIC connection. I rejected that solution due to sweeping
changes required.
AI disclosure
OpenAI GPT-5.5 was used to improve upon the first version of this PR.
CoPilot-generated code review snippets were used to amend the PR with
suggested fixes.