diff options
| author | Austin Clements <austin@google.com> | 2014-10-27 17:17:06 -0400 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2014-10-27 17:17:06 -0400 |
| commit | 5a653089ef756ecda170e4ee030480d547496362 (patch) | |
| tree | fe2c3550eb05fe487b5870dfef3d06972582c1a9 /src/net/lookup.go | |
| parent | 32c75a2d3d121f31ace325d48d9fcbdde58cc042 (diff) | |
| parent | 3e62d2184ab2d2ac6053e3f4af5e3f99902c1e32 (diff) | |
| download | go-5a653089ef756ecda170e4ee030480d547496362.tar.xz | |
[dev.power64] all: merge default into dev.power64
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/164110043
Diffstat (limited to 'src/net/lookup.go')
| -rw-r--r-- | src/net/lookup.go | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/src/net/lookup.go b/src/net/lookup.go index 20f20578cd..aeffe6c9b7 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -40,10 +40,16 @@ func lookupIPMerge(host string) (addrs []IP, err error) { addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) { return lookupIP(host) }) + return lookupIPReturn(addrsi, err, shared) +} + +// lookupIPReturn turns the return values from singleflight.Do into +// the return values from LookupIP. +func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IP, error) { if err != nil { return nil, err } - addrs = addrsi.([]IP) + addrs := addrsi.([]IP) if shared { clone := make([]IP, len(addrs)) copy(clone, addrs) @@ -52,41 +58,40 @@ func lookupIPMerge(host string) (addrs []IP, err error) { return addrs, nil } +// lookupIPDeadline looks up a hostname with a deadline. func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) { if deadline.IsZero() { return lookupIPMerge(host) } - // TODO(bradfitz): consider pushing the deadline down into the - // name resolution functions. But that involves fixing it for - // the native Go resolver, cgo, Windows, etc. - // - // In the meantime, just use a goroutine. Most users affected - // by http://golang.org/issue/2631 are due to TCP connections - // to unresponsive hosts, not DNS. + // We could push the deadline down into the name resolution + // functions. However, the most commonly used implementation + // calls getaddrinfo, which has no timeout. + timeout := deadline.Sub(time.Now()) if timeout <= 0 { - err = errTimeout - return + return nil, errTimeout } t := time.NewTimer(timeout) defer t.Stop() - type res struct { - addrs []IP - err error - } - resc := make(chan res, 1) - go func() { - a, err := lookupIPMerge(host) - resc <- res{a, err} - }() + + ch := lookupGroup.DoChan(host, func() (interface{}, error) { + return lookupIP(host) + }) + select { case <-t.C: - err = errTimeout - case r := <-resc: - addrs, err = r.addrs, r.err + // The DNS lookup timed out for some reason. Force + // future requests to start the DNS lookup again + // rather than waiting for the current lookup to + // complete. See issue 8602. + lookupGroup.Forget(host) + + return nil, errTimeout + + case r := <-ch: + return lookupIPReturn(r.v, r.err, r.shared) } - return } // LookupPort looks up the port for the given network and service. |
