mirror of https://github.com/grpc/grpc-java.git
util: Graceful switch to new LB when leaving CONNECTING
Previously it would wait for the new LB to enter READY. However, that prevents there being an upper-bound on how long the old policy will continue to be used. The point of graceful switch is to avoid RPCs seeing increased latency when we swap config. We don't want it to prevent the system from becoming eventually consistent.
This commit is contained in:
parent
7507a9ec06
commit
2e260a4bbc
|
|
@ -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.
|
||||
*
|
||||
* <p>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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue