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
19package balancer
20
21import (
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.
51type 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.
96type 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.
108type 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.
121func connectedAddress(scs SubConnState) resolver.Address {
122 return scs.connectedAddress
123}
124
125// setConnectedAddress sets the connected address for a SubConnState.
126func 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.
134type Producer any