Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc: perform a blocking close of the balancer in ccb #6497

Merged
merged 1 commit into from Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 2 additions & 4 deletions balancer_conn_wrappers.go
Expand Up @@ -226,11 +226,9 @@ func (ccb *ccBalancerWrapper) closeBalancer(m ccbMode) {
}
ccb.mu.Unlock()

// Give enqueued callbacks a chance to finish.
// Give enqueued callbacks a chance to finish before closing the balancer.
<-done
// Spawn a goroutine to close the balancer (since it may block trying to
// cleanup all allocated resources) and return early.
go b.Close()
b.Close()
}

// exitIdleMode is invoked by grpc when the channel exits idle mode either
Expand Down
9 changes: 6 additions & 3 deletions test/idleness_test.go
Expand Up @@ -408,17 +408,20 @@ func (s) TestChannelIdleness_Enabled_IdleTimeoutRacesWithRPCs(t *testing.T) {
// Verify that the ClientConn moves to READY.
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
awaitState(ctx, t, cc, connectivity.Ready)
client := testgrpc.NewTestServiceClient(cc)
if _, err := client.EmptyCall(ctx, &testpb.Empty{}); err != nil {
t.Errorf("EmptyCall RPC failed: %v", err)
}
Comment on lines 408 to +414
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just delete this entirely? We're going to perform 20 RPCs after this anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This acts as a sanity check to ensure that the channel is READY and can make RPCs before we get to our actual test. So, if for some reason, the channel doesn't become READY, then we will fail here and will have a better signal instead of failing down below wherein we might initially think the failure is because of a bad interaction between idle timeout firing and a new RPC being made.


// Make an RPC every defaultTestShortTimeout duration so as to race with the
// idle timeout. Whether the idle timeout wins the race or the RPC wins the
// race, RPCs must succeed.
client := testgrpc.NewTestServiceClient(cc)
for i := 0; i < 20; i++ {
<-time.After(defaultTestShortTimeout)
if _, err := client.EmptyCall(ctx, &testpb.Empty{}); err != nil {
t.Errorf("EmptyCall RPC failed: %v", err)
t.Fatalf("EmptyCall RPC failed: %v", err)
}
t.Logf("Iteration %d succeeded", i)
}
}

Expand Down