dubbo.apache.org/dubbo-go/v3@v3.1.1/xds/balancer/priority/balancer_child.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. 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 * 20 * Copyright 2021 gRPC authors. 21 * 22 */ 23 24 package priority 25 26 import ( 27 "google.golang.org/grpc/balancer" 28 "google.golang.org/grpc/balancer/base" 29 30 "google.golang.org/grpc/connectivity" 31 32 "google.golang.org/grpc/resolver" 33 34 "google.golang.org/grpc/serviceconfig" 35 ) 36 37 type childBalancer struct { 38 name string 39 parent *priorityBalancer 40 bb *ignoreResolveNowBalancerBuilder 41 42 ignoreReresolutionRequests bool 43 config serviceconfig.LoadBalancingConfig 44 rState resolver.State 45 46 started bool 47 state balancer.State 48 } 49 50 // newChildBalancer creates a child balancer place holder, but doesn't 51 // build/start the child balancer. 52 func newChildBalancer(name string, parent *priorityBalancer, bb balancer.Builder) *childBalancer { 53 return &childBalancer{ 54 name: name, 55 parent: parent, 56 bb: newIgnoreResolveNowBalancerBuilder(bb, false), 57 started: false, 58 // Start with the connecting state and picker with re-pick error, so 59 // that when a priority switch causes this child picked before it's 60 // balancing policy is created, a re-pick will happen. 61 state: balancer.State{ 62 ConnectivityState: connectivity.Connecting, 63 Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable), 64 }, 65 } 66 } 67 68 // updateBuilder updates builder for the child, but doesn't build. 69 func (cb *childBalancer) updateBuilder(bb balancer.Builder) { 70 cb.bb = newIgnoreResolveNowBalancerBuilder(bb, cb.ignoreReresolutionRequests) 71 } 72 73 // updateConfig sets childBalancer's config and state, but doesn't send update to 74 // the child balancer. 75 func (cb *childBalancer) updateConfig(child *Child, rState resolver.State) { 76 cb.ignoreReresolutionRequests = child.IgnoreReresolutionRequests 77 cb.config = child.Config.Config 78 cb.rState = rState 79 } 80 81 // start builds the child balancer if it's not already started. 82 // 83 // It doesn't do it directly. It asks the balancer group to build it. 84 func (cb *childBalancer) start() { 85 if cb.started { 86 return 87 } 88 cb.started = true 89 cb.parent.bg.Add(cb.name, cb.bb) 90 } 91 92 // sendUpdate sends the addresses and config to the child balancer. 93 func (cb *childBalancer) sendUpdate() { 94 cb.bb.updateIgnoreResolveNow(cb.ignoreReresolutionRequests) 95 // TODO: return and aggregate the returned error in the parent. 96 err := cb.parent.bg.UpdateClientConnState(cb.name, balancer.ClientConnState{ 97 ResolverState: cb.rState, 98 BalancerConfig: cb.config, 99 }) 100 if err != nil { 101 cb.parent.logger.Warnf("failed to update ClientConn state for child %v: %v", cb.name, err) 102 } 103 } 104 105 // stop stops the child balancer and resets the state. 106 // 107 // It doesn't do it directly. It asks the balancer group to remove it. 108 // 109 // Note that the underlying balancer group could keep the child in a cache. 110 func (cb *childBalancer) stop() { 111 if !cb.started { 112 return 113 } 114 cb.parent.bg.Remove(cb.name) 115 cb.started = false 116 cb.state = balancer.State{ 117 ConnectivityState: connectivity.Connecting, 118 Picker: base.NewErrPicker(balancer.ErrNoSubConnAvailable), 119 } 120 }