Skip to content

Commit ca49ae7

Browse files
address reviews
1 parent a6fcb7e commit ca49ae7

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

balancer/rls/control_channel.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ func (cc *controlChannel) monitorConnectivityState() {
208208
seenTransientFailure = true
209209
}
210210

211-
// Only reset backoff if we're returning to READY after a failure
211+
// Only reset backoff when recovering from TRANSIENT_FAILURE to READY.
212+
// This prevents unnecessary backoff resets for benign state transitions
213+
// like READY → IDLE → READY, which don't represent actual failures.
212214
if s == connectivity.Ready {
213215
if seenTransientFailure {
214216
cc.logger.Infof("Control channel back to READY after TRANSIENT_FAILURE")

balancer/rls/control_channel_test.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -517,13 +517,15 @@ func (s) TestControlChannelConnectivityStateTransitions(t *testing.T) {
517517
// Start an RLS server
518518
rlsServer, _ := rlstest.SetupFakeRLSServer(t, nil)
519519

520-
// Setup callback to count invocations
520+
// Setup callback to count invocations with synchronization
521521
callbackCount := 0
522522
var mu sync.Mutex
523+
callbackInvoked := make(chan struct{}, 10)
523524
callback := func() {
524525
mu.Lock()
525526
callbackCount++
526527
mu.Unlock()
528+
callbackInvoked <- struct{}{}
527529
}
528530

529531
// Create control channel
@@ -533,18 +535,45 @@ func (s) TestControlChannelConnectivityStateTransitions(t *testing.T) {
533535
}
534536
defer ctrlCh.close()
535537

536-
// Give the channel time to reach initial READY state
537-
time.Sleep(100 * time.Millisecond)
538+
// Wait for initial READY state by checking connectivity state buffer
539+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
540+
defer cancel()
541+
initialReady := false
542+
for !initialReady {
543+
select {
544+
case <-ctx.Done():
545+
t.Fatal("Timeout waiting for initial READY state")
546+
default:
547+
if ctrlCh.cc.GetState() == connectivity.Ready {
548+
initialReady = true
549+
} else {
550+
time.Sleep(10 * time.Millisecond)
551+
}
552+
}
553+
}
538554

539555
// Inject the test state sequence
540556
for _, state := range tt.states {
541557
ctrlCh.OnMessage(state)
542-
// Give time for the monitoring goroutine to process the state
543-
time.Sleep(50 * time.Millisecond)
544558
}
545559

546-
// Give extra time for any pending callbacks
547-
time.Sleep(100 * time.Millisecond)
560+
// Wait for expected callbacks to be invoked
561+
for i := 0; i < tt.wantCallbackCount; i++ {
562+
select {
563+
case <-callbackInvoked:
564+
// Callback received as expected
565+
case <-time.After(defaultTestTimeout):
566+
t.Fatalf("Timeout waiting for callback %d/%d", i+1, tt.wantCallbackCount)
567+
}
568+
}
569+
570+
// Ensure no extra callbacks are invoked
571+
select {
572+
case <-callbackInvoked:
573+
t.Fatal("Received more callbacks than expected")
574+
case <-time.After(100 * time.Millisecond):
575+
// Expected: no more callbacks
576+
}
548577

549578
mu.Lock()
550579
gotCallbackCount := callbackCount

0 commit comments

Comments
 (0)