@@ -117,6 +117,15 @@ type NewSubConnOptions struct {
117
117
HealthCheckEnabled bool
118
118
}
119
119
120
+ // State contains the balancer's state relevant to the gRPC ClientConn.
121
+ type State struct {
122
+ // State contains the connectivity state of the balancer, which is used to
123
+ // determine the state of the ClientConn.
124
+ ConnectivityState connectivity.State
125
+ // Picker is used to choose connections (SubConns) for RPCs.
126
+ Picker V2Picker
127
+ }
128
+
120
129
// ClientConn represents a gRPC ClientConn.
121
130
//
122
131
// This interface is to be implemented by gRPC. Users should not need a
@@ -137,8 +146,17 @@ type ClientConn interface {
137
146
//
138
147
// gRPC will update the connectivity state of the ClientConn, and will call pick
139
148
// on the new picker to pick new SubConn.
149
+ //
150
+ // Deprecated: use UpdateState instead
140
151
UpdateBalancerState (s connectivity.State , p Picker )
141
152
153
+ // UpdateState notifies gRPC that the balancer's internal state has
154
+ // changed.
155
+ //
156
+ // gRPC will update the connectivity state of the ClientConn, and will call pick
157
+ // on the new picker to pick new SubConns.
158
+ UpdateState (State )
159
+
142
160
// ResolveNow is called by balancer to notify gRPC to do a name resolving.
143
161
ResolveNow (resolver.ResolveNowOptions )
144
162
@@ -185,11 +203,19 @@ type ConfigParser interface {
185
203
ParseConfig (LoadBalancingConfigJSON json.RawMessage ) (serviceconfig.LoadBalancingConfig , error )
186
204
}
187
205
188
- // PickOptions contains addition information for the Pick operation.
189
- type PickOptions struct {
206
+ // PickOptions is a type alias of PickInfo for legacy reasons.
207
+ //
208
+ // Deprecated: use PickInfo instead.
209
+ type PickOptions = PickInfo
210
+
211
+ // PickInfo contains additional information for the Pick operation.
212
+ type PickInfo struct {
190
213
// FullMethodName is the method name that NewClientStream() is called
191
214
// with. The canonical format is /service/Method.
192
215
FullMethodName string
216
+ // Ctx is the RPC's context, and may contain relevant RPC-level information
217
+ // like the outgoing header metadata.
218
+ Ctx context.Context
193
219
}
194
220
195
221
// DoneInfo contains additional information for done.
@@ -215,14 +241,16 @@ var (
215
241
ErrNoSubConnAvailable = errors .New ("no SubConn is available" )
216
242
// ErrTransientFailure indicates all SubConns are in TransientFailure.
217
243
// WaitForReady RPCs will block, non-WaitForReady RPCs will fail.
218
- ErrTransientFailure = errors .New ("all SubConns are in TransientFailure" )
244
+ ErrTransientFailure = TransientFailureError ( errors .New ("all SubConns are in TransientFailure" ) )
219
245
)
220
246
221
247
// Picker is used by gRPC to pick a SubConn to send an RPC.
222
248
// Balancer is expected to generate a new picker from its snapshot every time its
223
249
// internal state has changed.
224
250
//
225
251
// The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState().
252
+ //
253
+ // Deprecated: use V2Picker instead
226
254
type Picker interface {
227
255
// Pick returns the SubConn to be used to send the RPC.
228
256
// The returned SubConn must be one returned by NewSubConn().
@@ -243,18 +271,76 @@ type Picker interface {
243
271
//
244
272
// If the returned error is not nil:
245
273
// - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState()
246
- // - If the error is ErrTransientFailure:
274
+ // - If the error is ErrTransientFailure or implements IsTransientFailure()
275
+ // bool, returning true:
247
276
// - If the RPC is wait-for-ready, gRPC will block until UpdateBalancerState()
248
277
// is called to pick again;
249
278
// - Otherwise, RPC will fail with unavailable error.
250
279
// - Else (error is other non-nil error):
251
- // - The RPC will fail with unavailable error.
280
+ // - The RPC will fail with the error's status code, or Unknown if it is
281
+ // not a status error.
252
282
//
253
283
// The returned done() function will be called once the rpc has finished,
254
284
// with the final status of that RPC. If the SubConn returned is not a
255
285
// valid SubConn type, done may not be called. done may be nil if balancer
256
286
// doesn't care about the RPC status.
257
- Pick (ctx context.Context , opts PickOptions ) (conn SubConn , done func (DoneInfo ), err error )
287
+ Pick (ctx context.Context , info PickInfo ) (conn SubConn , done func (DoneInfo ), err error )
288
+ }
289
+
290
+ // PickResult contains information related to a connection chosen for an RPC.
291
+ type PickResult struct {
292
+ // SubConn is the connection to use for this pick, if its state is Ready.
293
+ // If the state is not Ready, gRPC will block the RPC until a new Picker is
294
+ // provided by the balancer (using ClientConn.UpdateState). The SubConn
295
+ // must be one returned by ClientConn.NewSubConn.
296
+ SubConn SubConn
297
+
298
+ // Done is called when the RPC is completed. If the SubConn is not ready,
299
+ // this will be called with a nil parameter. If the SubConn is not a valid
300
+ // type, Done may not be called. May be nil if the balancer does not wish
301
+ // to be notified when the RPC completes.
302
+ Done func (DoneInfo )
303
+ }
304
+
305
+ type transientFailureError struct {
306
+ error
307
+ }
308
+
309
+ func (e * transientFailureError ) IsTransientFailure () bool { return true }
310
+
311
+ // TransientFailureError wraps err in an error implementing
312
+ // IsTransientFailure() bool, returning true.
313
+ func TransientFailureError (err error ) error {
314
+ return & transientFailureError {error : err }
315
+ }
316
+
317
+ // V2Picker is used by gRPC to pick a SubConn to send an RPC.
318
+ // Balancer is expected to generate a new picker from its snapshot every time its
319
+ // internal state has changed.
320
+ //
321
+ // The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState().
322
+ type V2Picker interface {
323
+ // Pick returns the connection to use for this RPC and related information.
324
+ //
325
+ // Pick should not block. If the balancer needs to do I/O or any blocking
326
+ // or time-consuming work to service this call, it should return
327
+ // ErrNoSubConnAvailable, and the Pick call will be repeated by gRPC when
328
+ // the Picker is updated (using ClientConn.UpdateState).
329
+ //
330
+ // If an error is returned:
331
+ //
332
+ // - If the error is ErrNoSubConnAvailable, gRPC will block until a new
333
+ // Picker is provided by the balancer (using ClientConn.UpdateState).
334
+ //
335
+ // - If the error implements IsTransientFailure() bool, returning true,
336
+ // wait for ready RPCs will wait, but non-wait for ready RPCs will be
337
+ // terminated with this error's Error() string and status code
338
+ // Unavailable.
339
+ //
340
+ // - Any other errors terminate all RPCs with the code and message
341
+ // provided. If the error is not a status error, it will be converted by
342
+ // gRPC to a status error with code Unknown.
343
+ Pick (info PickInfo ) (PickResult , error )
258
344
}
259
345
260
346
// Balancer takes input from gRPC, manages SubConns, and collects and aggregates
@@ -292,8 +378,11 @@ type Balancer interface {
292
378
293
379
// SubConnState describes the state of a SubConn.
294
380
type SubConnState struct {
381
+ // ConnectivityState is the connectivity state of the SubConn.
295
382
ConnectivityState connectivity.State
296
- // TODO: add last connection error
383
+ // ConnectionError is set if the ConnectivityState is TransientFailure,
384
+ // describing the reason the SubConn failed. Otherwise, it is nil.
385
+ ConnectionError error
297
386
}
298
387
299
388
// ClientConnState describes the state of a ClientConn relevant to the
@@ -335,9 +424,8 @@ type V2Balancer interface {
335
424
//
336
425
// It's not thread safe.
337
426
type ConnectivityStateEvaluator struct {
338
- numReady uint64 // Number of addrConns in ready state.
339
- numConnecting uint64 // Number of addrConns in connecting state.
340
- numTransientFailure uint64 // Number of addrConns in transientFailure.
427
+ numReady uint64 // Number of addrConns in ready state.
428
+ numConnecting uint64 // Number of addrConns in connecting state.
341
429
}
342
430
343
431
// RecordTransition records state change happening in subConn and based on that
@@ -357,8 +445,6 @@ func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newState conne
357
445
cse .numReady += updateVal
358
446
case connectivity .Connecting :
359
447
cse .numConnecting += updateVal
360
- case connectivity .TransientFailure :
361
- cse .numTransientFailure += updateVal
362
448
}
363
449
}
364
450
0 commit comments