net: implement query-response fast failover in builtin dns stub resolver
Speed improvements via code cleanup, and changes to make go dns behave more like glibc resolver. See https://groups.google.com/forum/#!topic/golang-dev/lV-0aHqxVeo
Fixes issue 6579.
Benchmark results on linux/amd64
benchmark old ns/op new ns/op delta
BenchmarkGoLookupIP 4831903 2572937 -46.75%
BenchmarkGoLookupIPNoSuchHost 10114105 2419641 -76.08%
BenchmarkGoLookupIPWithBrokenNameServer 20007735624 5004490730 -74.99%
benchmark old allocs new allocs delta
BenchmarkGoLookupIP 287 288 0.35%
BenchmarkGoLookupIPNoSuchHost 204 102 -50.00%
BenchmarkGoLookupIPWithBrokenNameServer 410 358 -12.68%
benchmark old bytes new bytes delta
BenchmarkGoLookupIP 13181 13271 0.68%
BenchmarkGoLookupIPNoSuchHost 17260 8714 -49.51%
BenchmarkGoLookupIPWithBrokenNameServer 28160 22432 -20.34%
Thanks Josh, made suggested edits if you want to peek again. Mikio? Thanks, Alex https://codereview.appspot.com/128820043/diff/80001/src/pkg/net/dnsclient_unix.go ...
10 years, 8 months ago
(2014-08-28 23:40:24 UTC)
#6
On 2014/08/28 15:40:41, bradfitz wrote: > Mikio, Josh, could you review? will try this afternoon. ...
10 years, 8 months ago
(2014-08-28 23:48:13 UTC)
#7
On 2014/08/28 15:40:41, bradfitz wrote:
> Mikio, Josh, could you review?
will try this afternoon.
> The tree closes in a few days.
i think the martial law doesn't affect bugfixes, am i missing something?
thanks. can you please change the cl descr something like; implement query-response fast failover in ...
10 years, 8 months ago
(2014-08-29 14:33:01 UTC)
#8
thanks. can you please change the cl descr something like; implement
query-response fast failover in builtin dns stub resolver
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
File src/pkg/net/dnsclient_unix.go (right):
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:176: if err != nil {
you miss that lastErr is just an interface and we can do type assertion.
if err != nil {
lastErr = &DNSError{
:
}
if nerr, ok := err.(Error); ok && nerr.Timeout() {
lastErr.(*DNSError).IsTimeout = true
}
continue
}
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:325: if count(name, '.') < cfg.dnsConfig.ndots {
sorry i missed this change in previous review. can you please make a separate cl
for this change even if we still don't support partial/absolute lookup using
search-list+ndots in builtin stub resolver.
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:381: }
you can write this like the following:
type racer struct {
qtype uint16
rrs []dnsRR
error
}
lane := make(chan racer, 1)
qtypes := []uint16{dnsTypeA, dnsTypeAAAA}
for _, qtype := range qtypes {
go func(qtype uint16) {
_, rrs, err := lookup(name, qtype)
lane <- racer{qtype, rrs, err}
}(qtype)
}
var lastErr error
for range qtypes {
racer := <-lane
if racer.error != nil {
lastErr = racer.error
continue
}
switch racer.qtype {
case dnsTypeA:
addrs = append(addrs, convertRR_A(racer.rrs)...)
case dnsTypeAAAA:
addrs = append(addrs, convertRR_AAAA(racer.rrs)...)
}
}
if lastErr != nil {
return nil, lastErr
}
return addrs, nil
}
Thanks. Made recommended changes and will move suggested logic cleanup and associated test into another ...
10 years, 8 months ago
(2014-08-29 18:16:30 UTC)
#9
Thanks. Made recommended changes and will move suggested logic cleanup and
associated test into another CL.
PTAL.
Thanks,
Alex
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
File src/pkg/net/dnsclient_unix.go (right):
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:176: if err != nil {
On 2014/08/29 14:33:00, mikio wrote:
> you miss that lastErr is just an interface and we can do type assertion.
>
> if err != nil {
> lastErr = &DNSError{
> :
> }
> if nerr, ok := err.(Error); ok && nerr.Timeout() {
> lastErr.(*DNSError).IsTimeout = true
> }
> continue
> }
Done.
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:325: if count(name, '.') < cfg.dnsConfig.ndots {
On 2014/08/29 14:33:00, mikio wrote:
> sorry i missed this change in previous review. can you please make a separate
cl
> for this change even if we still don't support partial/absolute lookup using
> search-list+ndots in builtin stub resolver.
Done. I put the broken code back and will open new issue/CL.
https://codereview.appspot.com/128820043/diff/100001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:381: }
On 2014/08/29 14:33:00, mikio wrote:
> you can write this like the following:
>
> type racer struct {
> qtype uint16
> rrs []dnsRR
> error
> }
> lane := make(chan racer, 1)
> qtypes := []uint16{dnsTypeA, dnsTypeAAAA}
> for _, qtype := range qtypes {
> go func(qtype uint16) {
> _, rrs, err := lookup(name, qtype)
> lane <- racer{qtype, rrs, err}
> }(qtype)
> }
> var lastErr error
> for range qtypes {
> racer := <-lane
> if racer.error != nil {
> lastErr = racer.error
> continue
> }
> switch racer.qtype {
> case dnsTypeA:
> addrs = append(addrs, convertRR_A(racer.rrs)...)
> case dnsTypeAAAA:
> addrs = append(addrs, convertRR_AAAA(racer.rrs)...)
> }
> }
> if lastErr != nil {
> return nil, lastErr
> }
> return addrs, nil
> }
Done with two caveats. First, this cause 20% jump in allocs in test cases.
I've been trying to push this change for a year now, so I'm not going to argue
against it, just an FYI.
Second - the old logic returned addresses if they existed, so I tried to mimic
that by using if len(addrs) == 0 && lastErr != nil. If you are against this
prior behavior we can change, but why even have a lastErr when we can just bail
out if the first query errors?
Hi, PTAL. Mikio/Josh - please see below, your thoughts on hopefully this last blocker very ...
10 years, 8 months ago
(2014-08-29 23:04:00 UTC)
#11
Hi,
PTAL. Mikio/Josh - please see below, your thoughts on hopefully this last
blocker very welcome.
Thanks,
Alex
https://codereview.appspot.com/128820043/diff/160001/src/pkg/net/dnsclient_un...
File src/pkg/net/dnsclient_unix.go (right):
https://codereview.appspot.com/128820043/diff/160001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:385: lane := make(chan racer, 1)
On 2014/08/29 22:47:48, josharian wrote:
> If you're going to return early, you need to have a big enough buffer for all
> goroutines to send, on pain of leaking.
>
> So move this down a line and change to
>
> lane := make(chan racer, len(qtypes))
>
> (That is assuming that returning early is the right thing to do, which I don't
> know.)
Done. Thanks for this.
My only goal here is scenario where query one returns noSuchHost immediately,
and query 2 was dropped or otherwise timed out. No need to wait on query 2 in
this scenario, so it would be nice to return early.
If however this introduces possibility of leak, I will revert to lastErr method
suggested. Thoughts?
> If however this introduces possibility of leak, I will revert to lastErr method > ...
10 years, 8 months ago
(2014-08-30 00:55:57 UTC)
#12
> If however this introduces possibility of leak, I will revert to lastErr
method
> suggested. Thoughts?
It shouldn't leak now. As for whether the behavior is correct, I defer to Mikio.
Would you mind updating this to apply cleanly against tip? Thanks. And thanks
again for your perseverance with this.
https://codereview.appspot.com/128820043/diff/180001/src/pkg/net/dnsclient_un...
File src/pkg/net/dnsclient_unix.go (right):
https://codereview.appspot.com/128820043/diff/180001/src/pkg/net/dnsclient_un...
src/pkg/net/dnsclient_unix.go:385: qtypes := []uint16{dnsTypeA, dnsTypeAAAA}
Nit: Use [...]uint16, so len(qtypes) will be a compile-time constant.
On Friday, August 29, 2014 4:04:00 PM UTC-7, Alex Skinner wrote: > My only goal ...
10 years, 8 months ago
(2014-08-30 01:21:09 UTC)
#13
On Friday, August 29, 2014 4:04:00 PM UTC-7, Alex Skinner wrote:
> My only goal here is scenario where query one returns noSuchHost
> immediately, and query 2 was dropped or otherwise timed out. No need to
> wait on query 2 in this scenario, so it would be nice to return early.
The previous behavior is preferable: ignore errors if any lookups succeed. As
it is currently, it will only succeed if a domain has both A and AAAA records.
If it is missing either type, then this will return a noSuchHost error.
On 2014/08/29 18:16:30, axaxs wrote: > Done with two caveats. First, this cause 20% jump ...
10 years, 8 months ago
(2014-08-30 01:40:05 UTC)
#14
On 2014/08/29 18:16:30, axaxs wrote:
> Done with two caveats. First, this cause 20% jump in allocs in test cases.
> I've been trying to push this change for a year now, so I'm not going to argue
> against it, just an FYI.
sure, but we can avoid tons of internal dns encoding/decoding helpers that make
unnecessary allocations later, maybe in go1.5.
Absolutely right! I was just complaining about this recently on a golang-dev thread. Thank you ...
10 years, 8 months ago
(2014-08-30 01:53:32 UTC)
#15
Absolutely right! I was just complaining about this recently on a
golang-dev thread. Thank you very much, fixed.
Mikio - Can we fix this in 1.5? IMO, an auth answer for a missing type
should not be a no such host. Only NXDOMAIN should. Thoughts?
Thanks,
Alex
On Fri, Aug 29, 2014 at 9:21 PM, <abursavich@gmail.com> wrote:
> On Friday, August 29, 2014 4:04:00 PM UTC-7, Alex Skinner wrote:
> > My only goal here is scenario where query one returns noSuchHost
> > immediately, and query 2 was dropped or otherwise timed out. No need to
> > wait on query 2 in this scenario, so it would be nice to return early.
>
> The previous behavior is preferable: ignore errors if any lookups
> succeed. As it is currently, it will only succeed if a domain has both A
> and AAAA records. If it is missing either type, then this will return a
> noSuchHost error.
I think(hope) it is finalized now after a mix of edits from advice from Mikio, ...
10 years, 8 months ago
(2014-08-30 01:54:54 UTC)
#16
I think(hope) it is finalized now after a mix of edits from advice from
Mikio, Josh, and abursavich.
PTAL.
Thanks,
Alex
On Fri, Aug 29, 2014 at 9:40 PM, <mikioh.mikioh@gmail.com> wrote:
> On 2014/08/29 18:16:30, axaxs wrote:
>
> Done with two caveats. First, this cause 20% jump in allocs in test
>>
> cases.
>
>> I've been trying to push this change for a year now, so I'm not going
>>
> to argue
>
>> against it, just an FYI.
>>
>
> sure, but we can avoid tons of internal dns encoding/decoding helpers
> that make unnecessary allocations later, maybe in go1.5.
>
>
> https://codereview.appspot.com/128820043/
>
On Sat, Aug 30, 2014 at 10:53 AM, Alex Skinner <alex@lx.lc> wrote: > Mikio - ...
10 years, 8 months ago
(2014-08-30 02:29:44 UTC)
#17
On Sat, Aug 30, 2014 at 10:53 AM, Alex Skinner <alex@lx.lc> wrote:
> Mikio - Can we fix this in 1.5? IMO, an auth answer for a missing type
> should not be a no such host. Only NXDOMAIN should. Thoughts?
i'm happy if you have a plan for refactoring builtin dns stub resolver
comprehensively in go1.5.
*** Submitted as https://code.google.com/p/go/source/detail?r=a32faf936e45 *** net: implement query-response fast failover in builtin dns stub resolver ...
10 years, 8 months ago
(2014-08-30 04:12:53 UTC)
#20
*** Submitted as https://code.google.com/p/go/source/detail?r=a32faf936e45 ***
net: implement query-response fast failover in builtin dns stub resolver
Speed improvements via code cleanup, and changes to make go dns behave more like
glibc resolver. See
https://groups.google.com/forum/#!topic/golang-dev/lV-0aHqxVeo
Fixes issue 6579.
Benchmark results on linux/amd64
benchmark old ns/op new ns/op delta
BenchmarkGoLookupIP 4831903 2572937 -46.75%
BenchmarkGoLookupIPNoSuchHost 10114105 2419641 -76.08%
BenchmarkGoLookupIPWithBrokenNameServer 20007735624 5004490730 -74.99%
benchmark old allocs new allocs delta
BenchmarkGoLookupIP 287 288 0.35%
BenchmarkGoLookupIPNoSuchHost 204 102 -50.00%
BenchmarkGoLookupIPWithBrokenNameServer 410 358 -12.68%
benchmark old bytes new bytes delta
BenchmarkGoLookupIP 13181 13271 0.68%
BenchmarkGoLookupIPNoSuchHost 17260 8714 -49.51%
BenchmarkGoLookupIPWithBrokenNameServer 28160 22432 -20.34%
LGTM=mikioh.mikioh
R=golang-codereviews, mikioh.mikioh, bradfitz, josharian, abursavich
CC=golang-codereviews
https://codereview.appspot.com/128820043
Committer: Mikio Hara <mikioh.mikioh@gmail.com>
Issue 128820043: code review 128820043: net: improve behavior of unix native Go DNS queries
Created 10 years, 8 months ago by axaxs
Modified 10 years, 8 months ago
Reviewers: gobot
Base URL:
Comments: 33