...

Source file src/google.golang.org/grpc/balancer/conn_state_evaluator.go

Documentation: google.golang.org/grpc/balancer

     1  /*
     2   *
     3   * Copyright 2022 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 balancer
    20  
    21  import "google.golang.org/grpc/connectivity"
    22  
    23  // ConnectivityStateEvaluator takes the connectivity states of multiple SubConns
    24  // and returns one aggregated connectivity state.
    25  //
    26  // It's not thread safe.
    27  type ConnectivityStateEvaluator struct {
    28  	numReady            uint64 // Number of addrConns in ready state.
    29  	numConnecting       uint64 // Number of addrConns in connecting state.
    30  	numTransientFailure uint64 // Number of addrConns in transient failure state.
    31  	numIdle             uint64 // Number of addrConns in idle state.
    32  }
    33  
    34  // RecordTransition records state change happening in subConn and based on that
    35  // it evaluates what aggregated state should be.
    36  //
    37  //   - If at least one SubConn in Ready, the aggregated state is Ready;
    38  //   - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
    39  //   - Else if at least one SubConn is Idle, the aggregated state is Idle;
    40  //   - Else if at least one SubConn is TransientFailure (or there are no SubConns), the aggregated state is Transient Failure.
    41  //
    42  // Shutdown is not considered.
    43  func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State {
    44  	// Update counters.
    45  	for idx, state := range []connectivity.State{oldState, newState} {
    46  		updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
    47  		switch state {
    48  		case connectivity.Ready:
    49  			cse.numReady += updateVal
    50  		case connectivity.Connecting:
    51  			cse.numConnecting += updateVal
    52  		case connectivity.TransientFailure:
    53  			cse.numTransientFailure += updateVal
    54  		case connectivity.Idle:
    55  			cse.numIdle += updateVal
    56  		}
    57  	}
    58  	return cse.CurrentState()
    59  }
    60  
    61  // CurrentState returns the current aggregate conn state by evaluating the counters
    62  func (cse *ConnectivityStateEvaluator) CurrentState() connectivity.State {
    63  	// Evaluate.
    64  	if cse.numReady > 0 {
    65  		return connectivity.Ready
    66  	}
    67  	if cse.numConnecting > 0 {
    68  		return connectivity.Connecting
    69  	}
    70  	if cse.numIdle > 0 {
    71  		return connectivity.Idle
    72  	}
    73  	return connectivity.TransientFailure
    74  }
    75  

View as plain text