connectivity.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright 2018 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package balancer
  15. import "google.golang.org/grpc/connectivity"
  16. // connectivityStateEvaluator gets updated by addrConns when their
  17. // states transition, based on which it evaluates the state of
  18. // ClientConn.
  19. type connectivityStateEvaluator struct {
  20. numReady uint64 // Number of addrConns in ready state.
  21. numConnecting uint64 // Number of addrConns in connecting state.
  22. numTransientFailure uint64 // Number of addrConns in transientFailure.
  23. }
  24. // recordTransition records state change happening in every subConn and based on
  25. // that it evaluates what aggregated state should be.
  26. // It can only transition between Ready, Connecting and TransientFailure. Other states,
  27. // Idle and Shutdown are transitioned into by ClientConn; in the beginning of the connection
  28. // before any subConn is created ClientConn is in idle state. In the end when ClientConn
  29. // closes it is in Shutdown state.
  30. //
  31. // recordTransition should only be called synchronously from the same goroutine.
  32. func (cse *connectivityStateEvaluator) recordTransition(oldState, newState connectivity.State) connectivity.State {
  33. // Update counters.
  34. for idx, state := range []connectivity.State{oldState, newState} {
  35. updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
  36. switch state {
  37. case connectivity.Ready:
  38. cse.numReady += updateVal
  39. case connectivity.Connecting:
  40. cse.numConnecting += updateVal
  41. case connectivity.TransientFailure:
  42. cse.numTransientFailure += updateVal
  43. }
  44. }
  45. // Evaluate.
  46. if cse.numReady > 0 {
  47. return connectivity.Ready
  48. }
  49. if cse.numConnecting > 0 {
  50. return connectivity.Connecting
  51. }
  52. return connectivity.TransientFailure
  53. }