-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
I mentioned in #12476 that I would like to detect the time it took for DNS resolution phase of the Dial process in Dialer.Dial . The solution posted there was very hacky and adds unnecessarily to the API.
@bradfitz suggested
Perhaps
net.Dialercould have an optionalResolver, akin to howhttp.Clienthas an optionalTransport, orhttp.Serverhas an optionalErrorLog, etc.
This seems like an excellent idea. Here is how I propose we go about it by adding minimal complexity and preserving code compatibility.
I propose net package adds a new Resolver interface.
type Resolver interface {
Resolve(host string, deadline time.Time) (addrs []IPAddr, err error)
}
The signature of Resolver.Resolve is same as lookupIPDeadline which Dial eventually uses. Dialer gets an optional field CustomResolver of type Resolver.
The Resolver object (or nil) gets passed around thru the resolution process.
Dialer.Dial -> resolveAddrList -> internetAddrList .
internetAddrList currently always uses lookupIPDeadline, it would need to be changed such that if the passed custom resolver is not nil then use it, otherwise use lookupIPDeadline.
Other functions calling resolveAddrList or internetAddrList would need to be modified to add an extra nil argument . This does not break code compatibility because they are unexported functions.
Benefits of allowing a custom Resolver
- Allowing me to collect timing information as mentioned in net: I would like Dialer.Dial to provide the time it took to do DNS lookups and TCP Connect #12476
- Allowing users to implement their own DNS logic. Failovers, etc.
- Mocking for tests.
- Client side caching, pre-fetching, etc.
- In time, other packages ( like the superb github.com/miekg/dns ) could provide their own
Resolverimplementations. - Great for people like me who rely on Go to write network debugging tools.