gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/internal/balancer/clustermanager/clustermanager.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package clustermanager implements the cluster manager LB policy for xds. 20 package clustermanager 21 22 import ( 23 "encoding/json" 24 "fmt" 25 26 "gitee.com/ks-custle/core-gm/grpc/balancer" 27 "gitee.com/ks-custle/core-gm/grpc/grpclog" 28 "gitee.com/ks-custle/core-gm/grpc/internal/balancergroup" 29 internalgrpclog "gitee.com/ks-custle/core-gm/grpc/internal/grpclog" 30 "gitee.com/ks-custle/core-gm/grpc/internal/hierarchy" 31 "gitee.com/ks-custle/core-gm/grpc/internal/pretty" 32 "gitee.com/ks-custle/core-gm/grpc/resolver" 33 "gitee.com/ks-custle/core-gm/grpc/serviceconfig" 34 ) 35 36 const balancerName = "xds_cluster_manager_experimental" 37 38 func init() { 39 balancer.Register(bb{}) 40 } 41 42 type bb struct{} 43 44 func (bb) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer { 45 b := &bal{} 46 b.logger = prefixLogger(b) 47 b.stateAggregator = newBalancerStateAggregator(cc, b.logger) 48 b.stateAggregator.start() 49 b.bg = balancergroup.New(cc, opts, b.stateAggregator, b.logger) 50 b.bg.Start() 51 b.logger.Infof("Created") 52 return b 53 } 54 55 func (bb) Name() string { 56 return balancerName 57 } 58 59 func (bb) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { 60 return parseConfig(c) 61 } 62 63 type bal struct { 64 logger *internalgrpclog.PrefixLogger 65 66 // TODO: make this package not dependent on xds specific code. Same as for 67 // weighted target balancer. 68 bg *balancergroup.BalancerGroup 69 stateAggregator *balancerStateAggregator 70 71 children map[string]childConfig 72 } 73 74 func (b *bal) updateChildren(s balancer.ClientConnState, newConfig *lbConfig) { 75 update := false 76 addressesSplit := hierarchy.Group(s.ResolverState.Addresses) 77 78 // Remove sub-pickers and sub-balancers that are not in the new cluster list. 79 for name := range b.children { 80 if _, ok := newConfig.Children[name]; !ok { 81 b.stateAggregator.remove(name) 82 b.bg.Remove(name) 83 update = true 84 } 85 } 86 87 // For sub-balancers in the new cluster list, 88 // - add to balancer group if it's new, 89 // - forward the address/balancer config update. 90 for name, newT := range newConfig.Children { 91 if _, ok := b.children[name]; !ok { 92 // If this is a new sub-balancer, add it to the picker map. 93 b.stateAggregator.add(name) 94 // Then add to the balancer group. 95 b.bg.Add(name, balancer.Get(newT.ChildPolicy.Name)) 96 } 97 // TODO: handle error? How to aggregate errors and return? 98 _ = b.bg.UpdateClientConnState(name, balancer.ClientConnState{ 99 ResolverState: resolver.State{ 100 Addresses: addressesSplit[name], 101 ServiceConfig: s.ResolverState.ServiceConfig, 102 Attributes: s.ResolverState.Attributes, 103 }, 104 BalancerConfig: newT.ChildPolicy.Config, 105 }) 106 } 107 108 b.children = newConfig.Children 109 if update { 110 b.stateAggregator.buildAndUpdate() 111 } 112 } 113 114 func (b *bal) UpdateClientConnState(s balancer.ClientConnState) error { 115 newConfig, ok := s.BalancerConfig.(*lbConfig) 116 if !ok { 117 return fmt.Errorf("unexpected balancer config with type: %T", s.BalancerConfig) 118 } 119 b.logger.Infof("update with config %+v, resolver state %+v", pretty.ToJSON(s.BalancerConfig), s.ResolverState) 120 121 b.updateChildren(s, newConfig) 122 return nil 123 } 124 125 func (b *bal) ResolverError(err error) { 126 b.bg.ResolverError(err) 127 } 128 129 func (b *bal) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { 130 b.bg.UpdateSubConnState(sc, state) 131 } 132 133 func (b *bal) Close() { 134 b.stateAggregator.close() 135 b.bg.Close() 136 b.logger.Infof("Shutdown") 137 } 138 139 func (b *bal) ExitIdle() { 140 b.bg.ExitIdle() 141 } 142 143 const prefix = "[xds-cluster-manager-lb %p] " 144 145 var logger = grpclog.Component("xds") 146 147 func prefixLogger(p *bal) *internalgrpclog.PrefixLogger { 148 return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(prefix, p)) 149 }