Async::Scheduler#address_resolve calls Resolv.getaddresses, which breaks the expectation that resolution honors the platform's address-selection policy:
- Stdlib Ruby:
Addrinfo.foreach/Socket.tcp fall through to libc getaddrinfo. On dual-stack hosts where the OS prefers IPv6, AAAA records come back first.
- Under
Async: The scheduler hook routes through Resolv.getaddresses, and Resolv::DNS#each_address iterates IN::A before IN::AAAA, so A records come back first.
On an IPv6-only host (with no IPv4 egress) against a dual-stack endpoint, the IPv4 connect() hangs:
require "async"
require "net/http"
Async do
p Net::HTTP.get_response(URI "https://dualstack.example.com/").code
end.wait
The request succeeds without Async.
Async::Scheduler#address_resolvecallsResolv.getaddresses, which breaks the expectation that resolution honors the platform's address-selection policy:Addrinfo.foreach/Socket.tcpfall through to libcgetaddrinfo. On dual-stack hosts where the OS prefers IPv6, AAAA records come back first.Async: The scheduler hook routes throughResolv.getaddresses, andResolv::DNS#each_addressiteratesIN::AbeforeIN::AAAA, so A records come back first.On an IPv6-only host (with no IPv4 egress) against a dual-stack endpoint, the IPv4
connect()hangs:The request succeeds without
Async.