| 
									
										
										
										
											2025-02-06 12:14:37 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright 2024 gRPC authors. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package balancer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"google.golang.org/grpc/connectivity" | 
					
						
							|  |  |  | 	"google.golang.org/grpc/internal" | 
					
						
							|  |  |  | 	"google.golang.org/grpc/resolver" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A SubConn represents a single connection to a gRPC backend service. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // All SubConns start in IDLE, and will not try to connect. To trigger a | 
					
						
							|  |  |  | // connection attempt, Balancers must call Connect. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // If the connection attempt fails, the SubConn will transition to | 
					
						
							|  |  |  | // TRANSIENT_FAILURE for a backoff period, and then return to IDLE.  If the | 
					
						
							|  |  |  | // connection attempt succeeds, it will transition to READY. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // If a READY SubConn becomes disconnected, the SubConn will transition to IDLE. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // If a connection re-enters IDLE, Balancers must call Connect again to trigger | 
					
						
							|  |  |  | // a new connection attempt. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Each SubConn contains a list of addresses.  gRPC will try to connect to the | 
					
						
							|  |  |  | // addresses in sequence, and stop trying the remainder once the first | 
					
						
							|  |  |  | // connection is successful.  However, this behavior is deprecated.  SubConns | 
					
						
							|  |  |  | // should only use a single address. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // NOTICE: This interface is intended to be implemented by gRPC, or intercepted | 
					
						
							| 
									
										
										
										
											2025-03-10 09:23:45 +00:00
										 |  |  | // by custom load balancing polices.  Users should not need their own complete | 
					
						
							| 
									
										
										
										
											2025-02-06 12:14:37 +01:00
										 |  |  | // implementation of this interface -- they should always delegate to a SubConn | 
					
						
							|  |  |  | // returned by ClientConn.NewSubConn() by embedding it in their implementations. | 
					
						
							|  |  |  | // An embedded SubConn must never be nil, or runtime panics will occur. | 
					
						
							|  |  |  | type SubConn interface { | 
					
						
							|  |  |  | 	// UpdateAddresses updates the addresses used in this SubConn. | 
					
						
							|  |  |  | 	// gRPC checks if currently-connected address is still in the new list. | 
					
						
							|  |  |  | 	// If it's in the list, the connection will be kept. | 
					
						
							|  |  |  | 	// If it's not in the list, the connection will gracefully close, and | 
					
						
							|  |  |  | 	// a new connection will be created. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// This will trigger a state transition for the SubConn. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// Deprecated: this method will be removed.  Create new SubConns for new | 
					
						
							|  |  |  | 	// addresses instead. | 
					
						
							|  |  |  | 	UpdateAddresses([]resolver.Address) | 
					
						
							|  |  |  | 	// Connect starts the connecting for this SubConn. | 
					
						
							|  |  |  | 	Connect() | 
					
						
							|  |  |  | 	// GetOrBuildProducer returns a reference to the existing Producer for this | 
					
						
							|  |  |  | 	// ProducerBuilder in this SubConn, or, if one does not currently exist, | 
					
						
							|  |  |  | 	// creates a new one and returns it.  Returns a close function which may be | 
					
						
							|  |  |  | 	// called when the Producer is no longer needed.  Otherwise the producer | 
					
						
							|  |  |  | 	// will automatically be closed upon connection loss or subchannel close. | 
					
						
							|  |  |  | 	// Should only be called on a SubConn in state Ready.  Otherwise the | 
					
						
							|  |  |  | 	// producer will be unable to create streams. | 
					
						
							|  |  |  | 	GetOrBuildProducer(ProducerBuilder) (p Producer, close func()) | 
					
						
							|  |  |  | 	// Shutdown shuts down the SubConn gracefully.  Any started RPCs will be | 
					
						
							|  |  |  | 	// allowed to complete.  No future calls should be made on the SubConn. | 
					
						
							|  |  |  | 	// One final state update will be delivered to the StateListener (or | 
					
						
							|  |  |  | 	// UpdateSubConnState; deprecated) with ConnectivityState of Shutdown to | 
					
						
							|  |  |  | 	// indicate the shutdown operation.  This may be delivered before | 
					
						
							|  |  |  | 	// in-progress RPCs are complete and the actual connection is closed. | 
					
						
							|  |  |  | 	Shutdown() | 
					
						
							|  |  |  | 	// RegisterHealthListener registers a health listener that receives health | 
					
						
							|  |  |  | 	// updates for a Ready SubConn. Only one health listener can be registered | 
					
						
							|  |  |  | 	// at a time. A health listener should be registered each time the SubConn's | 
					
						
							|  |  |  | 	// connectivity state changes to READY. Registering a health listener when | 
					
						
							|  |  |  | 	// the connectivity state is not READY may result in undefined behaviour. | 
					
						
							|  |  |  | 	// This method must not be called synchronously while handling an update | 
					
						
							|  |  |  | 	// from a previously registered health listener. | 
					
						
							|  |  |  | 	RegisterHealthListener(func(SubConnState)) | 
					
						
							|  |  |  | 	// EnforceSubConnEmbedding is included to force implementers to embed | 
					
						
							|  |  |  | 	// another implementation of this interface, allowing gRPC to add methods | 
					
						
							|  |  |  | 	// without breaking users. | 
					
						
							|  |  |  | 	internal.EnforceSubConnEmbedding | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A ProducerBuilder is a simple constructor for a Producer.  It is used by the | 
					
						
							|  |  |  | // SubConn to create producers when needed. | 
					
						
							|  |  |  | type ProducerBuilder interface { | 
					
						
							|  |  |  | 	// Build creates a Producer.  The first parameter is always a | 
					
						
							|  |  |  | 	// grpc.ClientConnInterface (a type to allow creating RPCs/streams on the | 
					
						
							|  |  |  | 	// associated SubConn), but is declared as `any` to avoid a dependency | 
					
						
							|  |  |  | 	// cycle.  Build also returns a close function that will be called when all | 
					
						
							|  |  |  | 	// references to the Producer have been given up for a SubConn, or when a | 
					
						
							|  |  |  | 	// connectivity state change occurs on the SubConn.  The close function | 
					
						
							|  |  |  | 	// should always block until all asynchronous cleanup work is completed. | 
					
						
							|  |  |  | 	Build(grpcClientConnInterface any) (p Producer, close func()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SubConnState describes the state of a SubConn. | 
					
						
							|  |  |  | type SubConnState struct { | 
					
						
							|  |  |  | 	// ConnectivityState is the connectivity state of the SubConn. | 
					
						
							|  |  |  | 	ConnectivityState connectivity.State | 
					
						
							|  |  |  | 	// ConnectionError is set if the ConnectivityState is TransientFailure, | 
					
						
							|  |  |  | 	// describing the reason the SubConn failed.  Otherwise, it is nil. | 
					
						
							|  |  |  | 	ConnectionError error | 
					
						
							|  |  |  | 	// connectedAddr contains the connected address when ConnectivityState is | 
					
						
							|  |  |  | 	// Ready. Otherwise, it is indeterminate. | 
					
						
							|  |  |  | 	connectedAddress resolver.Address | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // connectedAddress returns the connected address for a SubConnState. The | 
					
						
							|  |  |  | // address is only valid if the state is READY. | 
					
						
							|  |  |  | func connectedAddress(scs SubConnState) resolver.Address { | 
					
						
							|  |  |  | 	return scs.connectedAddress | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // setConnectedAddress sets the connected address for a SubConnState. | 
					
						
							|  |  |  | func setConnectedAddress(scs *SubConnState, addr resolver.Address) { | 
					
						
							|  |  |  | 	scs.connectedAddress = addr | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A Producer is a type shared among potentially many consumers.  It is | 
					
						
							|  |  |  | // associated with a SubConn, and an implementation will typically contain | 
					
						
							|  |  |  | // other methods to provide additional functionality, e.g. configuration or | 
					
						
							|  |  |  | // subscription registration. | 
					
						
							|  |  |  | type Producer any |