mirror of https://github.com/grpc/grpc-java.git
core: In PF, disjoint update while READY should transition to IDLE
This is the same as if we received a GOAWAY. We wait for the next RPC to begin connecting again. This is InternalSubchannel's behavior.
This commit is contained in:
parent
f20167d602
commit
ee3ffef3ee
|
@ -152,20 +152,18 @@ final class PickFirstLeafLoadBalancer extends LoadBalancer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldAddrs.size() == 0 || rawConnectivityState == CONNECTING
|
if (oldAddrs.size() == 0) {
|
||||||
|| rawConnectivityState == READY) {
|
// Make tests happy; they don't properly assume starting in CONNECTING
|
||||||
// start connection attempt at first address
|
|
||||||
rawConnectivityState = CONNECTING;
|
rawConnectivityState = CONNECTING;
|
||||||
updateBalancingState(CONNECTING, new Picker(PickResult.withNoResult()));
|
updateBalancingState(CONNECTING, new Picker(PickResult.withNoResult()));
|
||||||
cancelScheduleTask();
|
}
|
||||||
requestConnection();
|
|
||||||
|
|
||||||
} else if (rawConnectivityState == IDLE) {
|
if (rawConnectivityState == READY) {
|
||||||
// start connection attempt at first address when requested
|
// connect from beginning when prompted
|
||||||
SubchannelPicker picker = new RequestConnectionPicker(this);
|
rawConnectivityState = IDLE;
|
||||||
updateBalancingState(IDLE, picker);
|
updateBalancingState(IDLE, new RequestConnectionPicker(this));
|
||||||
|
|
||||||
} else if (rawConnectivityState == TRANSIENT_FAILURE) {
|
} else if (rawConnectivityState == CONNECTING || rawConnectivityState == TRANSIENT_FAILURE) {
|
||||||
// start connection attempt at first address
|
// start connection attempt at first address
|
||||||
cancelScheduleTask();
|
cancelScheduleTask();
|
||||||
requestConnection();
|
requestConnection();
|
||||||
|
|
|
@ -1121,10 +1121,17 @@ public class PickFirstLeafLoadBalancerTest {
|
||||||
loadBalancer.acceptResolvedAddresses(
|
loadBalancer.acceptResolvedAddresses(
|
||||||
ResolvedAddresses.newBuilder().setAddresses(newServers).setAttributes(affinity).build());
|
ResolvedAddresses.newBuilder().setAddresses(newServers).setAttributes(affinity).build());
|
||||||
inOrder.verify(mockSubchannel1).shutdown();
|
inOrder.verify(mockSubchannel1).shutdown();
|
||||||
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
|
inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
|
||||||
|
inOrder.verify(mockSubchannel3, never()).start(stateListenerCaptor.capture());
|
||||||
|
|
||||||
|
// Trigger connection creation
|
||||||
|
picker = pickerCaptor.getValue();
|
||||||
|
assertEquals(PickResult.withNoResult(), picker.pickSubchannel(mockArgs));
|
||||||
inOrder.verify(mockSubchannel3).start(stateListenerCaptor.capture());
|
inOrder.verify(mockSubchannel3).start(stateListenerCaptor.capture());
|
||||||
SubchannelStateListener stateListener3 = stateListenerCaptor.getValue();
|
SubchannelStateListener stateListener3 = stateListenerCaptor.getValue();
|
||||||
inOrder.verify(mockSubchannel3).requestConnection();
|
inOrder.verify(mockSubchannel3).requestConnection();
|
||||||
|
stateListener3.onSubchannelState(ConnectivityStateInfo.forNonError(CONNECTING));
|
||||||
|
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
|
||||||
|
|
||||||
if (enableHappyEyeballs) {
|
if (enableHappyEyeballs) {
|
||||||
forwardTimeByConnectionDelay();
|
forwardTimeByConnectionDelay();
|
||||||
|
@ -1171,17 +1178,19 @@ public class PickFirstLeafLoadBalancerTest {
|
||||||
loadBalancer.acceptResolvedAddresses(
|
loadBalancer.acceptResolvedAddresses(
|
||||||
ResolvedAddresses.newBuilder().setAddresses(newestServers).setAttributes(affinity).build());
|
ResolvedAddresses.newBuilder().setAddresses(newestServers).setAttributes(affinity).build());
|
||||||
inOrder.verify(mockSubchannel3).shutdown();
|
inOrder.verify(mockSubchannel3).shutdown();
|
||||||
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
|
inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
|
||||||
inOrder.verify(mockSubchannel1n2).start(stateListenerCaptor.capture());
|
assertEquals(IDLE, loadBalancer.getConcludedConnectivityState());
|
||||||
stateListener = stateListenerCaptor.getValue();
|
|
||||||
assertEquals(CONNECTING, loadBalancer.getConcludedConnectivityState());
|
|
||||||
picker = pickerCaptor.getValue();
|
picker = pickerCaptor.getValue();
|
||||||
|
|
||||||
// Calling pickSubchannel() twice gave the same result
|
// Calling pickSubchannel() twice gave the same result
|
||||||
assertEquals(picker.pickSubchannel(mockArgs), picker.pickSubchannel(mockArgs));
|
assertEquals(picker.pickSubchannel(mockArgs), picker.pickSubchannel(mockArgs));
|
||||||
|
|
||||||
// But the picker calls requestConnection() only once
|
// But the picker calls requestConnection() only once
|
||||||
|
inOrder.verify(mockSubchannel1n2).start(stateListenerCaptor.capture());
|
||||||
|
stateListener = stateListenerCaptor.getValue();
|
||||||
inOrder.verify(mockSubchannel1n2).requestConnection();
|
inOrder.verify(mockSubchannel1n2).requestConnection();
|
||||||
|
stateListener.onSubchannelState(ConnectivityStateInfo.forNonError(CONNECTING));
|
||||||
|
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
|
||||||
assertEquals(PickResult.withNoResult(), pickerCaptor.getValue().pickSubchannel(mockArgs));
|
assertEquals(PickResult.withNoResult(), pickerCaptor.getValue().pickSubchannel(mockArgs));
|
||||||
assertEquals(CONNECTING, loadBalancer.getConcludedConnectivityState());
|
assertEquals(CONNECTING, loadBalancer.getConcludedConnectivityState());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue