deduplicate dns record in lookup (#1454)

deduplicate dns record in lookup
This commit is contained in:
lyuxuan 2017-08-23 13:45:01 -07:00 committed by GitHub
parent 25d6e52b68
commit 9b6ac7ddb7
2 changed files with 32 additions and 29 deletions

View File

@ -141,8 +141,8 @@ type dnsWatcher struct {
r *dnsResolver r *dnsResolver
host string host string
port string port string
// The latest resolved address list // The latest resolved address set
curAddrs []*Update curAddrs map[string]*Update
ctx context.Context ctx context.Context
cancel context.CancelFunc cancel context.CancelFunc
t *time.Timer t *time.Timer
@ -192,28 +192,24 @@ type AddrMetadataGRPCLB struct {
// compileUpdate compares the old resolved addresses and newly resolved addresses, // compileUpdate compares the old resolved addresses and newly resolved addresses,
// and generates an update list // and generates an update list
func (w *dnsWatcher) compileUpdate(newAddrs []*Update) []*Update { func (w *dnsWatcher) compileUpdate(newAddrs map[string]*Update) []*Update {
update := make(map[Update]bool) var res []*Update
for _, u := range newAddrs { for a, u := range w.curAddrs {
update[*u] = true if _, ok := newAddrs[a]; !ok {
} u.Op = Delete
for _, u := range w.curAddrs { res = append(res, u)
if _, ok := update[*u]; ok {
delete(update, *u)
continue
} }
update[Update{Addr: u.Addr, Op: Delete, Metadata: u.Metadata}] = true
} }
res := make([]*Update, 0, len(update)) for a, u := range newAddrs {
for k := range update { if _, ok := w.curAddrs[a]; !ok {
tmp := k res = append(res, u)
res = append(res, &tmp) }
} }
return res return res
} }
func (w *dnsWatcher) lookupSRV() []*Update { func (w *dnsWatcher) lookupSRV() map[string]*Update {
var newAddrs []*Update newAddrs := make(map[string]*Update)
_, srvs, err := lookupSRV(w.ctx, "grpclb", "tcp", w.host) _, srvs, err := lookupSRV(w.ctx, "grpclb", "tcp", w.host)
if err != nil { if err != nil {
grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err) grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err)
@ -231,15 +227,16 @@ func (w *dnsWatcher) lookupSRV() []*Update {
grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err)
continue continue
} }
newAddrs = append(newAddrs, &Update{Addr: a + ":" + strconv.Itoa(int(s.Port)), addr := a + ":" + strconv.Itoa(int(s.Port))
Metadata: AddrMetadataGRPCLB{AddrType: GRPCLB, ServerName: s.Target}}) newAddrs[addr] = &Update{Addr: addr,
Metadata: AddrMetadataGRPCLB{AddrType: GRPCLB, ServerName: s.Target}}
} }
} }
return newAddrs return newAddrs
} }
func (w *dnsWatcher) lookupHost() []*Update { func (w *dnsWatcher) lookupHost() map[string]*Update {
var newAddrs []*Update newAddrs := make(map[string]*Update)
addrs, err := lookupHost(w.ctx, w.host) addrs, err := lookupHost(w.ctx, w.host)
if err != nil { if err != nil {
grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err) grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err)
@ -251,7 +248,8 @@ func (w *dnsWatcher) lookupHost() []*Update {
grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err)
continue continue
} }
newAddrs = append(newAddrs, &Update{Addr: a + ":" + w.port}) addr := a + ":" + w.port
newAddrs[addr] = &Update{Addr: addr}
} }
return newAddrs return newAddrs
} }

View File

@ -84,17 +84,22 @@ func TestCompileUpdate(t *testing.T) {
[]string{"1.0.0.2", "1.0.0.3", "1.0.0.6"}, []string{"1.0.0.2", "1.0.0.3", "1.0.0.6"},
[]*Update{{Op: Delete, Addr: "1.0.0.1"}, {Op: Add, Addr: "1.0.0.2"}, {Op: Delete, Addr: "1.0.0.5"}, {Op: Add, Addr: "1.0.0.6"}}, []*Update{{Op: Delete, Addr: "1.0.0.1"}, {Op: Add, Addr: "1.0.0.2"}, {Op: Delete, Addr: "1.0.0.5"}, {Op: Add, Addr: "1.0.0.6"}},
}, },
{
[]string{"1.0.0.1", "1.0.0.1", "1.0.0.2"},
[]string{"1.0.0.1"},
[]*Update{{Op: Delete, Addr: "1.0.0.2"}},
},
} }
var w dnsWatcher var w dnsWatcher
for _, c := range tests { for _, c := range tests {
w.curAddrs = make([]*Update, len(c.oldAddrs)) w.curAddrs = make(map[string]*Update)
newUpdates := make([]*Update, len(c.newAddrs)) newUpdates := make(map[string]*Update)
for i, a := range c.oldAddrs { for _, a := range c.oldAddrs {
w.curAddrs[i] = &Update{Addr: a} w.curAddrs[a] = &Update{Addr: a}
} }
for i, a := range c.newAddrs { for _, a := range c.newAddrs {
newUpdates[i] = &Update{Addr: a} newUpdates[a] = &Update{Addr: a}
} }
r := w.compileUpdate(newUpdates) r := w.compileUpdate(newUpdates)
if !reflect.DeepEqual(toMap(c.want), toMap(r)) { if !reflect.DeepEqual(toMap(c.want), toMap(r)) {