diff --git a/util/src/main/java/io/grpc/util/GracefulSwitchLoadBalancer.java b/util/src/main/java/io/grpc/util/GracefulSwitchLoadBalancer.java index 72c41886ad..e36eec1ff2 100644 --- a/util/src/main/java/io/grpc/util/GracefulSwitchLoadBalancer.java +++ b/util/src/main/java/io/grpc/util/GracefulSwitchLoadBalancer.java @@ -38,7 +38,8 @@ import javax.annotation.concurrent.NotThreadSafe; /** * A load balancer that gracefully swaps to a new lb policy. If the channel is currently in a state * other than READY, the new policy will be swapped into place immediately. Otherwise, the channel - * will keep using the old policy until the new policy reports READY or the old policy exits READY. + * will keep using the old policy until the new policy leaves CONNECTING or the old policy exits + * READY. * *

The child balancer and configuration is specified using service config. Config objects are * generally created by calling {@link #parseLoadBalancingPolicyConfig(List)} from a @@ -147,7 +148,7 @@ public final class GracefulSwitchLoadBalancer extends ForwardingLoadBalancer { checkState(currentLbIsReady, "there's pending lb while current lb has been out of READY"); pendingState = newState; pendingPicker = newPicker; - if (newState == ConnectivityState.READY) { + if (newState != ConnectivityState.CONNECTING) { swap(); } } else if (lb == currentLb) { diff --git a/util/src/test/java/io/grpc/util/GracefulSwitchLoadBalancerTest.java b/util/src/test/java/io/grpc/util/GracefulSwitchLoadBalancerTest.java index 9a4f569c14..5192d6a2a6 100644 --- a/util/src/test/java/io/grpc/util/GracefulSwitchLoadBalancerTest.java +++ b/util/src/test/java/io/grpc/util/GracefulSwitchLoadBalancerTest.java @@ -18,6 +18,7 @@ package io.grpc.util; import static com.google.common.truth.Truth.assertThat; import static io.grpc.ConnectivityState.CONNECTING; +import static io.grpc.ConnectivityState.IDLE; import static io.grpc.ConnectivityState.READY; import static io.grpc.ConnectivityState.TRANSIENT_FAILURE; import static io.grpc.util.GracefulSwitchLoadBalancer.BUFFER_PICKER; @@ -32,6 +33,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import com.google.common.testing.EqualsTester; +import io.grpc.ConnectivityState; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; import io.grpc.LoadBalancer; @@ -363,7 +365,21 @@ public class GracefulSwitchLoadBalancerTest { } @Test - public void updateBalancingStateIsGraceful() { + public void updateBalancingStateIsGraceful_Ready() { + updateBalancingStateIsGraceful(READY); + } + + @Test + public void updateBalancingStateIsGraceful_TransientFailure() { + updateBalancingStateIsGraceful(TRANSIENT_FAILURE); + } + + @Test + public void updateBalancingStateIsGraceful_Idle() { + updateBalancingStateIsGraceful(IDLE); + } + + public void updateBalancingStateIsGraceful(ConnectivityState swapsOnState) { assertIsOk(gracefulSwitchLb.acceptResolvedAddresses(addressesBuilder() .setLoadBalancingPolicyConfig(createConfig(lbPolicies[0], new Object())) .build())); @@ -392,11 +408,11 @@ public class GracefulSwitchLoadBalancerTest { helper2.updateBalancingState(CONNECTING, picker); verify(mockHelper, never()).updateBalancingState(CONNECTING, picker); - // lb2 reports READY + // lb2 reports swapsOnState SubchannelPicker picker2 = mock(SubchannelPicker.class); - helper2.updateBalancingState(READY, picker2); + helper2.updateBalancingState(swapsOnState, picker2); verify(lb0).shutdown(); - verify(mockHelper).updateBalancingState(READY, picker2); + verify(mockHelper).updateBalancingState(swapsOnState, picker2); assertIsOk(gracefulSwitchLb.acceptResolvedAddresses(addressesBuilder() .setLoadBalancingPolicyConfig(createConfig(lbPolicies[3], new Object())) @@ -407,7 +423,7 @@ public class GracefulSwitchLoadBalancerTest { helper3.updateBalancingState(CONNECTING, picker3); verify(mockHelper, never()).updateBalancingState(CONNECTING, picker3); - // lb2 out of READY + // lb2 out of swapsOnState picker2 = mock(SubchannelPicker.class); helper2.updateBalancingState(CONNECTING, picker2); verify(mockHelper, never()).updateBalancingState(CONNECTING, picker2);