func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan remoteBalancerInfo) error { updates, err := w.Next() if err != nil { return err } b.mu.Lock() defer b.mu.Unlock() if b.done { return grpc.ErrClientConnClosing } var bAddr remoteBalancerInfo if len(b.rbs) > 0 { bAddr = b.rbs[0] } for _, update := range updates { addr := grpc.Address{ Addr: update.Addr, Metadata: update.Metadata, } switch update.Op { case naming.Add: var exist bool for _, v := range b.rbs { // TODO: Is the same addr with different server name a different balancer? if addr == v.addr { exist = true break } } if exist { continue } b.rbs = append(b.rbs, remoteBalancerInfo{addr: addr}) case naming.Delete: for i, v := range b.rbs { if addr == v.addr { copy(b.rbs[i:], b.rbs[i+1:]) b.rbs = b.rbs[:len(b.rbs)-1] break } } default: grpclog.Println("Unknown update.Op ", update.Op) } } // TODO: Fall back to the basic round-robin load balancing if the resulting address is // not a load balancer. if len(b.rbs) > 0 { // For simplicity, always use the first one now. May revisit this decision later. if b.rbs[0] != bAddr { select { case <-ch: default: } ch <- b.rbs[0] } } return nil }
func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan remoteBalancerInfo) error { updates, err := w.Next() if err != nil { return err } b.mu.Lock() defer b.mu.Unlock() if b.done { return grpc.ErrClientConnClosing } var bAddr remoteBalancerInfo if len(b.rbs) > 0 { bAddr = b.rbs[0] } for _, update := range updates { switch update.Op { case naming.Add: var exist bool for _, v := range b.rbs { // TODO: Is the same addr with different server name a different balancer? if update.Addr == v.addr { exist = true break } } if exist { continue } md, ok := update.Metadata.(*Metadata) if !ok { // TODO: Revisit the handling here and may introduce some fallback mechanism. grpclog.Printf("The name resolution contains unexpected metadata %v", update.Metadata) continue } switch md.AddrType { case Backend: // TODO: Revisit the handling here and may introduce some fallback mechanism. grpclog.Printf("The name resolution does not give grpclb addresses") continue case GRPCLB: b.rbs = append(b.rbs, remoteBalancerInfo{ addr: update.Addr, name: md.ServerName, }) default: grpclog.Printf("Received unknow address type %d", md.AddrType) continue } case naming.Delete: for i, v := range b.rbs { if update.Addr == v.addr { copy(b.rbs[i:], b.rbs[i+1:]) b.rbs = b.rbs[:len(b.rbs)-1] break } } default: grpclog.Println("Unknown update.Op ", update.Op) } } // TODO: Fall back to the basic round-robin load balancing if the resulting address is // not a load balancer. if len(b.rbs) > 0 { // For simplicity, always use the first one now. May revisit this decision later. if b.rbs[0] != bAddr { select { case <-ch: default: } ch <- b.rbs[0] } } return nil }