Skip to content

Commit 0547980

Browse files
authored
Notify parent ClientConn to re-resolve in grpclb (grpc#1699)
The parent ClientConn should re-resolve when grpclb loses connection to the remote balancer. When the ClientConn inside grpclb gets a TransientFailure, it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's ResolveNow, and eventually results in re-resolve happening in parent ClientConn's resolver (DNS for example). This PR adds a method to balancer.ClientConn interface, so balancer can tell parent ClientConn to re-resolve.
1 parent e6549e6 commit 0547980

File tree

4 files changed

+99
-3
lines changed

4 files changed

+99
-3
lines changed

balancer/balancer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ type ClientConn interface {
109109
// on the new picker to pick new SubConn.
110110
UpdateBalancerState(s connectivity.State, p Picker)
111111

112+
// ResolveNow is called by balancer to notify gRPC to do a name resolving.
113+
ResolveNow(resolver.ResolveNowOption)
114+
112115
// Target returns the dial target for this ClientConn.
113116
Target() string
114117
}

balancer_conn_wrappers.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balanc
233233
ccb.cc.blockingpicker.updatePicker(p)
234234
}
235235

236+
func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOption) {
237+
ccb.cc.resolveNow(o)
238+
}
239+
236240
func (ccb *ccBalancerWrapper) Target() string {
237241
return ccb.cc.target
238242
}

grpclb.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1/messages"
3131
"google.golang.org/grpc/grpclog"
3232
"google.golang.org/grpc/resolver"
33-
"google.golang.org/grpc/resolver/manual"
3433
)
3534

3635
const (
@@ -121,7 +120,7 @@ func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) bal
121120
// scheme will be used to dial to remote LB, so we can send filtered address
122121
// updates to remote LB ClientConn using this manual resolver.
123122
scheme := "grpclb_internal_" + strconv.FormatInt(time.Now().UnixNano(), 36)
124-
r := manual.NewBuilderWithScheme(scheme)
123+
r := &lbManualResolver{scheme: scheme, ccb: cc}
125124

126125
var target string
127126
targetSplitted := strings.Split(cc.Target(), ":///")
@@ -159,7 +158,7 @@ type lbBalancer struct {
159158
// manualResolver is used in the remote LB ClientConn inside grpclb. When
160159
// resolved address updates are received by grpclb, filtered updates will be
161160
// send to remote LB ClientConn through this resolver.
162-
manualResolver *manual.Resolver
161+
manualResolver *lbManualResolver
163162
// The ClientConn to talk to the remote balancer.
164163
ccRemoteLB *ClientConn
165164

grpclb_util.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
*
3+
* Copyright 2016 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 grpc
20+
21+
import (
22+
"google.golang.org/grpc/balancer"
23+
"google.golang.org/grpc/resolver"
24+
)
25+
26+
// The parent ClientConn should re-resolve when grpclb loses connection to the
27+
// remote balancer. When the ClientConn inside grpclb gets a TransientFailure,
28+
// it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's
29+
// ResolveNow, and eventually results in re-resolve happening in parent
30+
// ClientConn's resolver (DNS for example).
31+
//
32+
// parent
33+
// ClientConn
34+
// +-----------------------------------------------------------------+
35+
// | parent +---------------------------------+ |
36+
// | DNS ClientConn | grpclb | |
37+
// | resolver balancerWrapper | | |
38+
// | + + | grpclb grpclb | |
39+
// | | | | ManualResolver ClientConn | |
40+
// | | | | + + | |
41+
// | | | | | | Transient | |
42+
// | | | | | | Failure | |
43+
// | | | | | <--------- | | |
44+
// | | | <--------------- | ResolveNow | | |
45+
// | | <--------- | ResolveNow | | | | |
46+
// | | ResolveNow | | | | | |
47+
// | | | | | | | |
48+
// | + + | + + | |
49+
// | +---------------------------------+ |
50+
// +-----------------------------------------------------------------+
51+
52+
// lbManualResolver is used by the ClientConn inside grpclb. It's a manual
53+
// resolver with a special ResolveNow() function.
54+
//
55+
// When ResolveNow() is called, it calls ResolveNow() on the parent ClientConn,
56+
// so when grpclb client lose contact with remote balancers, the parent
57+
// ClientConn's resolver will re-resolve.
58+
type lbManualResolver struct {
59+
scheme string
60+
ccr resolver.ClientConn
61+
62+
ccb balancer.ClientConn
63+
}
64+
65+
func (r *lbManualResolver) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOption) (resolver.Resolver, error) {
66+
r.ccr = cc
67+
return r, nil
68+
}
69+
70+
func (r *lbManualResolver) Scheme() string {
71+
return r.scheme
72+
}
73+
74+
// ResolveNow calls resolveNow on the parent ClientConn.
75+
func (r *lbManualResolver) ResolveNow(o resolver.ResolveNowOption) {
76+
r.ccb.ResolveNow(o)
77+
}
78+
79+
// Close is a noop for Resolver.
80+
func (*lbManualResolver) Close() {}
81+
82+
// NewAddress calls cc.NewAddress.
83+
func (r *lbManualResolver) NewAddress(addrs []resolver.Address) {
84+
r.ccr.NewAddress(addrs)
85+
}
86+
87+
// NewServiceConfig calls cc.NewServiceConfig.
88+
func (r *lbManualResolver) NewServiceConfig(sc string) {
89+
r.ccr.NewServiceConfig(sc)
90+
}

0 commit comments

Comments
 (0)