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  }