| Abhay Kumar | fe505f2 | 2025-11-10 14:16:31 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * |
| 3 | * Copyright 2024 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 ( |
| 22 | "google.golang.org/grpc/connectivity" |
| 23 | "google.golang.org/grpc/internal" |
| 24 | "google.golang.org/grpc/resolver" |
| 25 | ) |
| 26 | |
| 27 | // A SubConn represents a single connection to a gRPC backend service. |
| 28 | // |
| 29 | // All SubConns start in IDLE, and will not try to connect. To trigger a |
| 30 | // connection attempt, Balancers must call Connect. |
| 31 | // |
| 32 | // If the connection attempt fails, the SubConn will transition to |
| 33 | // TRANSIENT_FAILURE for a backoff period, and then return to IDLE. If the |
| 34 | // connection attempt succeeds, it will transition to READY. |
| 35 | // |
| 36 | // If a READY SubConn becomes disconnected, the SubConn will transition to IDLE. |
| 37 | // |
| 38 | // If a connection re-enters IDLE, Balancers must call Connect again to trigger |
| 39 | // a new connection attempt. |
| 40 | // |
| 41 | // Each SubConn contains a list of addresses. gRPC will try to connect to the |
| 42 | // addresses in sequence, and stop trying the remainder once the first |
| 43 | // connection is successful. However, this behavior is deprecated. SubConns |
| 44 | // should only use a single address. |
| 45 | // |
| 46 | // NOTICE: This interface is intended to be implemented by gRPC, or intercepted |
| 47 | // by custom load balancing polices. Users should not need their own complete |
| 48 | // implementation of this interface -- they should always delegate to a SubConn |
| 49 | // returned by ClientConn.NewSubConn() by embedding it in their implementations. |
| 50 | // An embedded SubConn must never be nil, or runtime panics will occur. |
| 51 | type SubConn interface { |
| 52 | // UpdateAddresses updates the addresses used in this SubConn. |
| 53 | // gRPC checks if currently-connected address is still in the new list. |
| 54 | // If it's in the list, the connection will be kept. |
| 55 | // If it's not in the list, the connection will gracefully close, and |
| 56 | // a new connection will be created. |
| 57 | // |
| 58 | // This will trigger a state transition for the SubConn. |
| 59 | // |
| 60 | // Deprecated: this method will be removed. Create new SubConns for new |
| 61 | // addresses instead. |
| 62 | UpdateAddresses([]resolver.Address) |
| 63 | // Connect starts the connecting for this SubConn. |
| 64 | Connect() |
| 65 | // GetOrBuildProducer returns a reference to the existing Producer for this |
| 66 | // ProducerBuilder in this SubConn, or, if one does not currently exist, |
| 67 | // creates a new one and returns it. Returns a close function which may be |
| 68 | // called when the Producer is no longer needed. Otherwise the producer |
| 69 | // will automatically be closed upon connection loss or subchannel close. |
| 70 | // Should only be called on a SubConn in state Ready. Otherwise the |
| 71 | // producer will be unable to create streams. |
| 72 | GetOrBuildProducer(ProducerBuilder) (p Producer, close func()) |
| 73 | // Shutdown shuts down the SubConn gracefully. Any started RPCs will be |
| 74 | // allowed to complete. No future calls should be made on the SubConn. |
| 75 | // One final state update will be delivered to the StateListener (or |
| 76 | // UpdateSubConnState; deprecated) with ConnectivityState of Shutdown to |
| 77 | // indicate the shutdown operation. This may be delivered before |
| 78 | // in-progress RPCs are complete and the actual connection is closed. |
| 79 | Shutdown() |
| 80 | // RegisterHealthListener registers a health listener that receives health |
| 81 | // updates for a Ready SubConn. Only one health listener can be registered |
| 82 | // at a time. A health listener should be registered each time the SubConn's |
| 83 | // connectivity state changes to READY. Registering a health listener when |
| 84 | // the connectivity state is not READY may result in undefined behaviour. |
| 85 | // This method must not be called synchronously while handling an update |
| 86 | // from a previously registered health listener. |
| 87 | RegisterHealthListener(func(SubConnState)) |
| 88 | // EnforceSubConnEmbedding is included to force implementers to embed |
| 89 | // another implementation of this interface, allowing gRPC to add methods |
| 90 | // without breaking users. |
| 91 | internal.EnforceSubConnEmbedding |
| 92 | } |
| 93 | |
| 94 | // A ProducerBuilder is a simple constructor for a Producer. It is used by the |
| 95 | // SubConn to create producers when needed. |
| 96 | type ProducerBuilder interface { |
| 97 | // Build creates a Producer. The first parameter is always a |
| 98 | // grpc.ClientConnInterface (a type to allow creating RPCs/streams on the |
| 99 | // associated SubConn), but is declared as `any` to avoid a dependency |
| 100 | // cycle. Build also returns a close function that will be called when all |
| 101 | // references to the Producer have been given up for a SubConn, or when a |
| 102 | // connectivity state change occurs on the SubConn. The close function |
| 103 | // should always block until all asynchronous cleanup work is completed. |
| 104 | Build(grpcClientConnInterface any) (p Producer, close func()) |
| 105 | } |
| 106 | |
| 107 | // SubConnState describes the state of a SubConn. |
| 108 | type SubConnState struct { |
| 109 | // ConnectivityState is the connectivity state of the SubConn. |
| 110 | ConnectivityState connectivity.State |
| 111 | // ConnectionError is set if the ConnectivityState is TransientFailure, |
| 112 | // describing the reason the SubConn failed. Otherwise, it is nil. |
| 113 | ConnectionError error |
| 114 | // connectedAddr contains the connected address when ConnectivityState is |
| 115 | // Ready. Otherwise, it is indeterminate. |
| 116 | connectedAddress resolver.Address |
| 117 | } |
| 118 | |
| 119 | // connectedAddress returns the connected address for a SubConnState. The |
| 120 | // address is only valid if the state is READY. |
| 121 | func connectedAddress(scs SubConnState) resolver.Address { |
| 122 | return scs.connectedAddress |
| 123 | } |
| 124 | |
| 125 | // setConnectedAddress sets the connected address for a SubConnState. |
| 126 | func setConnectedAddress(scs *SubConnState, addr resolver.Address) { |
| 127 | scs.connectedAddress = addr |
| 128 | } |
| 129 | |
| 130 | // A Producer is a type shared among potentially many consumers. It is |
| 131 | // associated with a SubConn, and an implementation will typically contain |
| 132 | // other methods to provide additional functionality, e.g. configuration or |
| 133 | // subscription registration. |
| 134 | type Producer any |