Skip to content

Commit ee3ffef

Browse files
committed
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.
1 parent f20167d commit ee3ffef

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

core/src/main/java/io/grpc/internal/PickFirstLeafLoadBalancer.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,18 @@ public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
152152
}
153153
}
154154

155-
if (oldAddrs.size() == 0 || rawConnectivityState == CONNECTING
156-
|| rawConnectivityState == READY) {
157-
// start connection attempt at first address
155+
if (oldAddrs.size() == 0) {
156+
// Make tests happy; they don't properly assume starting in CONNECTING
158157
rawConnectivityState = CONNECTING;
159158
updateBalancingState(CONNECTING, new Picker(PickResult.withNoResult()));
160-
cancelScheduleTask();
161-
requestConnection();
159+
}
162160

163-
} else if (rawConnectivityState == IDLE) {
164-
// start connection attempt at first address when requested
165-
SubchannelPicker picker = new RequestConnectionPicker(this);
166-
updateBalancingState(IDLE, picker);
161+
if (rawConnectivityState == READY) {
162+
// connect from beginning when prompted
163+
rawConnectivityState = IDLE;
164+
updateBalancingState(IDLE, new RequestConnectionPicker(this));
167165

168-
} else if (rawConnectivityState == TRANSIENT_FAILURE) {
166+
} else if (rawConnectivityState == CONNECTING || rawConnectivityState == TRANSIENT_FAILURE) {
169167
// start connection attempt at first address
170168
cancelScheduleTask();
171169
requestConnection();

core/src/test/java/io/grpc/internal/PickFirstLeafLoadBalancerTest.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,10 +1121,17 @@ public void updateAddresses_disjoint_ready_twice() {
11211121
loadBalancer.acceptResolvedAddresses(
11221122
ResolvedAddresses.newBuilder().setAddresses(newServers).setAttributes(affinity).build());
11231123
inOrder.verify(mockSubchannel1).shutdown();
1124-
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
1124+
inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
1125+
inOrder.verify(mockSubchannel3, never()).start(stateListenerCaptor.capture());
1126+
1127+
// Trigger connection creation
1128+
picker = pickerCaptor.getValue();
1129+
assertEquals(PickResult.withNoResult(), picker.pickSubchannel(mockArgs));
11251130
inOrder.verify(mockSubchannel3).start(stateListenerCaptor.capture());
11261131
SubchannelStateListener stateListener3 = stateListenerCaptor.getValue();
11271132
inOrder.verify(mockSubchannel3).requestConnection();
1133+
stateListener3.onSubchannelState(ConnectivityStateInfo.forNonError(CONNECTING));
1134+
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
11281135

11291136
if (enableHappyEyeballs) {
11301137
forwardTimeByConnectionDelay();
@@ -1171,17 +1178,19 @@ public void updateAddresses_disjoint_ready_twice() {
11711178
loadBalancer.acceptResolvedAddresses(
11721179
ResolvedAddresses.newBuilder().setAddresses(newestServers).setAttributes(affinity).build());
11731180
inOrder.verify(mockSubchannel3).shutdown();
1174-
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
1175-
inOrder.verify(mockSubchannel1n2).start(stateListenerCaptor.capture());
1176-
stateListener = stateListenerCaptor.getValue();
1177-
assertEquals(CONNECTING, loadBalancer.getConcludedConnectivityState());
1181+
inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
1182+
assertEquals(IDLE, loadBalancer.getConcludedConnectivityState());
11781183
picker = pickerCaptor.getValue();
11791184

11801185
// Calling pickSubchannel() twice gave the same result
11811186
assertEquals(picker.pickSubchannel(mockArgs), picker.pickSubchannel(mockArgs));
11821187

11831188
// But the picker calls requestConnection() only once
1189+
inOrder.verify(mockSubchannel1n2).start(stateListenerCaptor.capture());
1190+
stateListener = stateListenerCaptor.getValue();
11841191
inOrder.verify(mockSubchannel1n2).requestConnection();
1192+
stateListener.onSubchannelState(ConnectivityStateInfo.forNonError(CONNECTING));
1193+
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
11851194
assertEquals(PickResult.withNoResult(), pickerCaptor.getValue().pickSubchannel(mockArgs));
11861195
assertEquals(CONNECTING, loadBalancer.getConcludedConnectivityState());
11871196

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy