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
135