Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / google.golang.org / grpc / balancer / balancer.go
1 /*
2  *
3  * Copyright 2017 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 defines APIs for load balancing in gRPC.
20 // All APIs in this package are experimental.
21 package balancer
22
23 import (
24         "context"
25         "errors"
26         "net"
27         "strings"
28
29         "google.golang.org/grpc/connectivity"
30         "google.golang.org/grpc/credentials"
31         "google.golang.org/grpc/internal"
32         "google.golang.org/grpc/metadata"
33         "google.golang.org/grpc/resolver"
34 )
35
36 var (
37         // m is a map from name to balancer builder.
38         m = make(map[string]Builder)
39 )
40
41 // Register registers the balancer builder to the balancer map. b.Name
42 // (lowercased) will be used as the name registered with this builder.
43 //
44 // NOTE: this function must only be called during initialization time (i.e. in
45 // an init() function), and is not thread-safe. If multiple Balancers are
46 // registered with the same name, the one registered last will take effect.
47 func Register(b Builder) {
48         m[strings.ToLower(b.Name())] = b
49 }
50
51 // unregisterForTesting deletes the balancer with the given name from the
52 // balancer map.
53 //
54 // This function is not thread-safe.
55 func unregisterForTesting(name string) {
56         delete(m, name)
57 }
58
59 func init() {
60         internal.BalancerUnregister = unregisterForTesting
61 }
62
63 // Get returns the resolver builder registered with the given name.
64 // Note that the compare is done in a case-insensitive fashion.
65 // If no builder is register with the name, nil will be returned.
66 func Get(name string) Builder {
67         if b, ok := m[strings.ToLower(name)]; ok {
68                 return b
69         }
70         return nil
71 }
72
73 // SubConn represents a gRPC sub connection.
74 // Each sub connection contains a list of addresses. gRPC will
75 // try to connect to them (in sequence), and stop trying the
76 // remainder once one connection is successful.
77 //
78 // The reconnect backoff will be applied on the list, not a single address.
79 // For example, try_on_all_addresses -> backoff -> try_on_all_addresses.
80 //
81 // All SubConns start in IDLE, and will not try to connect. To trigger
82 // the connecting, Balancers must call Connect.
83 // When the connection encounters an error, it will reconnect immediately.
84 // When the connection becomes IDLE, it will not reconnect unless Connect is
85 // called.
86 //
87 // This interface is to be implemented by gRPC. Users should not need a
88 // brand new implementation of this interface. For the situations like
89 // testing, the new implementation should embed this interface. This allows
90 // gRPC to add new methods to this interface.
91 type SubConn interface {
92         // UpdateAddresses updates the addresses used in this SubConn.
93         // gRPC checks if currently-connected address is still in the new list.
94         // If it's in the list, the connection will be kept.
95         // If it's not in the list, the connection will gracefully closed, and
96         // a new connection will be created.
97         //
98         // This will trigger a state transition for the SubConn.
99         UpdateAddresses([]resolver.Address)
100         // Connect starts the connecting for this SubConn.
101         Connect()
102 }
103
104 // NewSubConnOptions contains options to create new SubConn.
105 type NewSubConnOptions struct {
106         // CredsBundle is the credentials bundle that will be used in the created
107         // SubConn. If it's nil, the original creds from grpc DialOptions will be
108         // used.
109         CredsBundle credentials.Bundle
110         // HealthCheckEnabled indicates whether health check service should be
111         // enabled on this SubConn
112         HealthCheckEnabled bool
113 }
114
115 // ClientConn represents a gRPC ClientConn.
116 //
117 // This interface is to be implemented by gRPC. Users should not need a
118 // brand new implementation of this interface. For the situations like
119 // testing, the new implementation should embed this interface. This allows
120 // gRPC to add new methods to this interface.
121 type ClientConn interface {
122         // NewSubConn is called by balancer to create a new SubConn.
123         // It doesn't block and wait for the connections to be established.
124         // Behaviors of the SubConn can be controlled by options.
125         NewSubConn([]resolver.Address, NewSubConnOptions) (SubConn, error)
126         // RemoveSubConn removes the SubConn from ClientConn.
127         // The SubConn will be shutdown.
128         RemoveSubConn(SubConn)
129
130         // UpdateBalancerState is called by balancer to notify gRPC that some internal
131         // state in balancer has changed.
132         //
133         // gRPC will update the connectivity state of the ClientConn, and will call pick
134         // on the new picker to pick new SubConn.
135         UpdateBalancerState(s connectivity.State, p Picker)
136
137         // ResolveNow is called by balancer to notify gRPC to do a name resolving.
138         ResolveNow(resolver.ResolveNowOption)
139
140         // Target returns the dial target for this ClientConn.
141         Target() string
142 }
143
144 // BuildOptions contains additional information for Build.
145 type BuildOptions struct {
146         // DialCreds is the transport credential the Balancer implementation can
147         // use to dial to a remote load balancer server. The Balancer implementations
148         // can ignore this if it does not need to talk to another party securely.
149         DialCreds credentials.TransportCredentials
150         // CredsBundle is the credentials bundle that the Balancer can use.
151         CredsBundle credentials.Bundle
152         // Dialer is the custom dialer the Balancer implementation can use to dial
153         // to a remote load balancer server. The Balancer implementations
154         // can ignore this if it doesn't need to talk to remote balancer.
155         Dialer func(context.Context, string) (net.Conn, error)
156         // ChannelzParentID is the entity parent's channelz unique identification number.
157         ChannelzParentID int64
158 }
159
160 // Builder creates a balancer.
161 type Builder interface {
162         // Build creates a new balancer with the ClientConn.
163         Build(cc ClientConn, opts BuildOptions) Balancer
164         // Name returns the name of balancers built by this builder.
165         // It will be used to pick balancers (for example in service config).
166         Name() string
167 }
168
169 // PickOptions contains addition information for the Pick operation.
170 type PickOptions struct {
171         // FullMethodName is the method name that NewClientStream() is called
172         // with. The canonical format is /service/Method.
173         FullMethodName string
174         // Header contains the metadata from the RPC's client header.  The metadata
175         // should not be modified; make a copy first if needed.
176         Header metadata.MD
177 }
178
179 // DoneInfo contains additional information for done.
180 type DoneInfo struct {
181         // Err is the rpc error the RPC finished with. It could be nil.
182         Err error
183         // Trailer contains the metadata from the RPC's trailer, if present.
184         Trailer metadata.MD
185         // BytesSent indicates if any bytes have been sent to the server.
186         BytesSent bool
187         // BytesReceived indicates if any byte has been received from the server.
188         BytesReceived bool
189 }
190
191 var (
192         // ErrNoSubConnAvailable indicates no SubConn is available for pick().
193         // gRPC will block the RPC until a new picker is available via UpdateBalancerState().
194         ErrNoSubConnAvailable = errors.New("no SubConn is available")
195         // ErrTransientFailure indicates all SubConns are in TransientFailure.
196         // WaitForReady RPCs will block, non-WaitForReady RPCs will fail.
197         ErrTransientFailure = errors.New("all SubConns are in TransientFailure")
198 )
199
200 // Picker is used by gRPC to pick a SubConn to send an RPC.
201 // Balancer is expected to generate a new picker from its snapshot every time its
202 // internal state has changed.
203 //
204 // The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState().
205 type Picker interface {
206         // Pick returns the SubConn to be used to send the RPC.
207         // The returned SubConn must be one returned by NewSubConn().
208         //
209         // This functions is expected to return:
210         // - a SubConn that is known to be READY;
211         // - ErrNoSubConnAvailable if no SubConn is available, but progress is being
212         //   made (for example, some SubConn is in CONNECTING mode);
213         // - other errors if no active connecting is happening (for example, all SubConn
214         //   are in TRANSIENT_FAILURE mode).
215         //
216         // If a SubConn is returned:
217         // - If it is READY, gRPC will send the RPC on it;
218         // - If it is not ready, or becomes not ready after it's returned, gRPC will block
219         //   until UpdateBalancerState() is called and will call pick on the new picker.
220         //
221         // If the returned error is not nil:
222         // - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState()
223         // - If the error is ErrTransientFailure:
224         //   - If the RPC is wait-for-ready, gRPC will block until UpdateBalancerState()
225         //     is called to pick again;
226         //   - Otherwise, RPC will fail with unavailable error.
227         // - Else (error is other non-nil error):
228         //   - The RPC will fail with unavailable error.
229         //
230         // The returned done() function will be called once the rpc has finished,
231         // with the final status of that RPC.  If the SubConn returned is not a
232         // valid SubConn type, done may not be called.  done may be nil if balancer
233         // doesn't care about the RPC status.
234         Pick(ctx context.Context, opts PickOptions) (conn SubConn, done func(DoneInfo), err error)
235 }
236
237 // Balancer takes input from gRPC, manages SubConns, and collects and aggregates
238 // the connectivity states.
239 //
240 // It also generates and updates the Picker used by gRPC to pick SubConns for RPCs.
241 //
242 // HandleSubConnectionStateChange, HandleResolvedAddrs and Close are guaranteed
243 // to be called synchronously from the same goroutine.
244 // There's no guarantee on picker.Pick, it may be called anytime.
245 type Balancer interface {
246         // HandleSubConnStateChange is called by gRPC when the connectivity state
247         // of sc has changed.
248         // Balancer is expected to aggregate all the state of SubConn and report
249         // that back to gRPC.
250         // Balancer should also generate and update Pickers when its internal state has
251         // been changed by the new state.
252         HandleSubConnStateChange(sc SubConn, state connectivity.State)
253         // HandleResolvedAddrs is called by gRPC to send updated resolved addresses to
254         // balancers.
255         // Balancer can create new SubConn or remove SubConn with the addresses.
256         // An empty address slice and a non-nil error will be passed if the resolver returns
257         // non-nil error to gRPC.
258         HandleResolvedAddrs([]resolver.Address, error)
259         // Close closes the balancer. The balancer is not required to call
260         // ClientConn.RemoveSubConn for its existing SubConns.
261         Close()
262 }
263
264 // ConnectivityStateEvaluator takes the connectivity states of multiple SubConns
265 // and returns one aggregated connectivity state.
266 //
267 // It's not thread safe.
268 type ConnectivityStateEvaluator struct {
269         numReady            uint64 // Number of addrConns in ready state.
270         numConnecting       uint64 // Number of addrConns in connecting state.
271         numTransientFailure uint64 // Number of addrConns in transientFailure.
272 }
273
274 // RecordTransition records state change happening in subConn and based on that
275 // it evaluates what aggregated state should be.
276 //
277 //  - If at least one SubConn in Ready, the aggregated state is Ready;
278 //  - Else if at least one SubConn in Connecting, the aggregated state is Connecting;
279 //  - Else the aggregated state is TransientFailure.
280 //
281 // Idle and Shutdown are not considered.
282 func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState connectivity.State) connectivity.State {
283         // Update counters.
284         for idx, state := range []connectivity.State{oldState, newState} {
285                 updateVal := 2*uint64(idx) - 1 // -1 for oldState and +1 for new.
286                 switch state {
287                 case connectivity.Ready:
288                         cse.numReady += updateVal
289                 case connectivity.Connecting:
290                         cse.numConnecting += updateVal
291                 case connectivity.TransientFailure:
292                         cse.numTransientFailure += updateVal
293                 }
294         }
295
296         // Evaluate.
297         if cse.numReady > 0 {
298                 return connectivity.Ready
299         }
300         if cse.numConnecting > 0 {
301                 return connectivity.Connecting
302         }
303         return connectivity.TransientFailure
304 }