Skip to content

Commit 2ef021f

Browse files
authored
New grpclb implementation (grpc#1558)
The new grpclb supports fallback to backends if remote balancer is unavailable
1 parent 10873b3 commit 2ef021f

File tree

13 files changed

+996
-863
lines changed

13 files changed

+996
-863
lines changed

balancer/balancer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ type PickOptions struct{}
128128
type DoneInfo struct {
129129
// Err is the rpc error the RPC finished with. It could be nil.
130130
Err error
131+
// BytesSent indicates if any bytes have been sent to the server.
132+
BytesSent bool
133+
// BytesReceived indicates if any byte has been received from the server.
134+
BytesReceived bool
131135
}
132136

133137
var (

call.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
277277
err = sendRequest(ctx, cc.dopts, cc.dopts.cp, c, callHdr, stream, t, args, topts)
278278
if err != nil {
279279
if done != nil {
280-
updateRPCInfoInContext(ctx, rpcInfo{
281-
bytesSent: true,
282-
bytesReceived: stream.BytesReceived(),
280+
done(balancer.DoneInfo{
281+
Err: err,
282+
BytesSent: true,
283+
BytesReceived: stream.BytesReceived(),
283284
})
284-
done(balancer.DoneInfo{Err: err})
285285
}
286286
// Retry a non-failfast RPC when
287287
// i) the server started to drain before this RPC was initiated.
@@ -301,11 +301,11 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
301301
err = recvResponse(ctx, cc.dopts, t, c, stream, reply)
302302
if err != nil {
303303
if done != nil {
304-
updateRPCInfoInContext(ctx, rpcInfo{
305-
bytesSent: true,
306-
bytesReceived: stream.BytesReceived(),
304+
done(balancer.DoneInfo{
305+
Err: err,
306+
BytesSent: true,
307+
BytesReceived: stream.BytesReceived(),
307308
})
308-
done(balancer.DoneInfo{Err: err})
309309
}
310310
if !c.failFast && stream.Unprocessed() {
311311
// In these cases, the server did not receive the data, but we still
@@ -323,12 +323,13 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
323323
c.traceInfo.tr.LazyLog(&payload{sent: false, msg: reply}, true)
324324
}
325325
t.CloseStream(stream, nil)
326+
err = stream.Status().Err()
326327
if done != nil {
327-
updateRPCInfoInContext(ctx, rpcInfo{
328-
bytesSent: true,
329-
bytesReceived: stream.BytesReceived(),
328+
done(balancer.DoneInfo{
329+
Err: err,
330+
BytesSent: true,
331+
BytesReceived: stream.BytesReceived(),
330332
})
331-
done(balancer.DoneInfo{Err: err})
332333
}
333334
if !c.failFast && stream.Unprocessed() {
334335
// In these cases, the server did not receive the data, but we still
@@ -339,6 +340,6 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
339340
continue
340341
}
341342
}
342-
return stream.Status().Err()
343+
return err
343344
}
344345
}

clientconn.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ type dialOptions struct {
9797
callOptions []CallOption
9898
// This is to support v1 balancer.
9999
balancerBuilder balancer.Builder
100+
// This is to support grpclb.
101+
resolverBuilder resolver.Builder
100102
}
101103

102104
const (
@@ -204,6 +206,13 @@ func WithBalancerBuilder(b balancer.Builder) DialOption {
204206
}
205207
}
206208

209+
// withResolverBuilder is only for grpclb.
210+
func withResolverBuilder(b resolver.Builder) DialOption {
211+
return func(o *dialOptions) {
212+
o.resolverBuilder = b
213+
}
214+
}
215+
207216
// WithServiceConfig returns a DialOption which has a channel to read the service configuration.
208217
// DEPRECATED: service config should be received through name resolver, as specified here.
209218
// https://github.com/grpc/grpc/blob/master/doc/service_config.md
@@ -283,18 +292,23 @@ func WithTimeout(d time.Duration) DialOption {
283292
}
284293
}
285294

295+
func withContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
296+
return func(o *dialOptions) {
297+
o.copts.Dialer = f
298+
}
299+
}
300+
286301
// WithDialer returns a DialOption that specifies a function to use for dialing network addresses.
287302
// If FailOnNonTempDialError() is set to true, and an error is returned by f, gRPC checks the error's
288303
// Temporary() method to decide if it should try to reconnect to the network address.
289304
func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
290-
return func(o *dialOptions) {
291-
o.copts.Dialer = func(ctx context.Context, addr string) (net.Conn, error) {
305+
return withContextDialer(
306+
func(ctx context.Context, addr string) (net.Conn, error) {
292307
if deadline, ok := ctx.Deadline(); ok {
293308
return f(addr, deadline.Sub(time.Now()))
294309
}
295310
return f(addr, 0)
296-
}
297-
}
311+
})
298312
}
299313

300314
// WithStatsHandler returns a DialOption that specifies the stats handler

0 commit comments

Comments
 (0)