Skip to content

Commit c073660

Browse files
authored
xds: Cleanup CDS balancer code and tests. (#3916)
1 parent 9a3c02f commit c073660

File tree

2 files changed

+229
-147
lines changed

2 files changed

+229
-147
lines changed

xds/internal/balancer/cdsbalancer/cdsbalancer.go

+23-27
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ type cdsBB struct{}
7272
// Build creates a new CDS balancer with the ClientConn.
7373
func (cdsBB) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
7474
b := &cdsBalancer{
75-
cc: cc,
76-
bOpts: opts,
77-
updateCh: buffer.NewUnbounded(),
78-
closed: grpcsync.NewEvent(),
75+
cc: cc,
76+
bOpts: opts,
77+
updateCh: buffer.NewUnbounded(),
78+
closed: grpcsync.NewEvent(),
79+
cancelWatch: func() {}, // No-op at this point.
7980
}
8081
b.logger = prefixLogger((b))
8182
b.logger.Infof("Created")
@@ -158,22 +159,15 @@ type cdsBalancer struct {
158159
// run is a long-running goroutine which handles all updates from gRPC. All
159160
// methods which are invoked directly by gRPC or xdsClient simply push an
160161
// update onto a channel which is read and acted upon right here.
161-
//
162-
// 1. Good clientConn updates lead to registration of a CDS watch. Updates with
163-
// error lead to cancellation of existing watch and propagation of the same
164-
// error to the edsBalancer.
165-
// 2. SubConn updates are passthrough and are simply handed over to the
166-
// underlying edsBalancer.
167-
// 3. Watch API updates lead to clientConn updates being invoked on the
168-
// underlying edsBalancer.
169-
// 4. Close results in cancellation of the CDS watch and closing of the
170-
// underlying edsBalancer and is the only way to exit this goroutine.
171162
func (b *cdsBalancer) run() {
172163
for {
173164
select {
174165
case u := <-b.updateCh.Get():
175166
b.updateCh.Load()
176167
switch update := u.(type) {
168+
// Good clientConn updates lead to registration of a CDS watch.
169+
// Updates with error lead to cancellation of existing watch and
170+
// propagation of the same error to the edsBalancer.
177171
case *ccUpdate:
178172
// We first handle errors, if any, and then proceed with handling
179173
// the update, only if the status quo has changed.
@@ -187,9 +181,7 @@ func (b *cdsBalancer) run() {
187181
// Since the cdsBalancer doesn't own the xdsClient object, we
188182
// don't have to bother about closing the old client here, but
189183
// we still need to cancel the watch on the old client.
190-
if b.cancelWatch != nil {
191-
b.cancelWatch()
192-
}
184+
b.cancelWatch()
193185
b.client = update.client
194186
}
195187
if update.clusterName != "" {
@@ -201,12 +193,18 @@ func (b *cdsBalancer) run() {
201193
}
202194
b.clusterToWatch = update.clusterName
203195
}
196+
197+
// SubConn updates are passthrough and are simply handed over to the
198+
// underlying edsBalancer.
204199
case *scUpdate:
205200
if b.edsLB == nil {
206201
b.logger.Errorf("xds: received scUpdate {%+v} with no edsBalancer", update)
207202
break
208203
}
209204
b.edsLB.UpdateSubConnState(update.subConn, update.state)
205+
206+
// Watch API updates lead to clientConn updates being invoked on the
207+
// underlying edsBalancer.
210208
case *watchUpdate:
211209
if err := update.err; err != nil {
212210
b.logger.Warningf("Watch error from xds-client %p: %v", b.client, err)
@@ -243,11 +241,13 @@ func (b *cdsBalancer) run() {
243241
b.logger.Errorf("xds: edsBalancer.UpdateClientConnState(%+v) returned error: %v", ccState, err)
244242
}
245243
}
244+
245+
// Close results in cancellation of the CDS watch and closing of the
246+
// underlying edsBalancer and is the only way to exit this goroutine.
246247
case <-b.closed.Done():
247-
if b.cancelWatch != nil {
248-
b.cancelWatch()
249-
b.cancelWatch = nil
250-
}
248+
b.cancelWatch()
249+
b.cancelWatch = func() {}
250+
251251
if b.edsLB != nil {
252252
b.edsLB.Close()
253253
b.edsLB = nil
@@ -282,11 +282,8 @@ func (b *cdsBalancer) handleErrorFromUpdate(err error, fromParent bool) {
282282
//
283283
// This is not necessary today, because xds client never sends connection
284284
// errors.
285-
286285
if fromParent && xdsclient.ErrType(err) == xdsclient.ErrorTypeResourceNotFound {
287-
if b.cancelWatch != nil {
288-
b.cancelWatch()
289-
}
286+
b.cancelWatch()
290287
}
291288
if b.edsLB != nil {
292289
b.edsLB.ResolverError(err)
@@ -319,7 +316,7 @@ func (b *cdsBalancer) UpdateClientConnState(state balancer.ClientConnState) erro
319316
return errBalancerClosed
320317
}
321318

322-
b.logger.Infof("Receive update from resolver, balancer config: %+v", state.BalancerConfig)
319+
b.logger.Infof("Received update from resolver, balancer config: %+v", state.BalancerConfig)
323320
// The errors checked here should ideally never happen because the
324321
// ServiceConfig in this case is prepared by the xdsResolver and is not
325322
// something that is received on the wire.
@@ -352,7 +349,6 @@ func (b *cdsBalancer) ResolverError(err error) {
352349
b.logger.Warningf("xds: received resolver error {%v} after cdsBalancer was closed", err)
353350
return
354351
}
355-
356352
b.updateCh.Put(&ccUpdate{err: err})
357353
}
358354

0 commit comments

Comments
 (0)