mirror of https://github.com/grpc/grpc-java.git
Remove implicit requestConnection() on IDLE from MultiChildLB
One LB no longer needs to extend ChildLbState and one has to start, so it is a bit of a wash. There are more LBs that need the auto-request logic, but if we have an API where subclasses override it without calling super then we can't change the implementation in the future. Adding behavior on top of a base class allows subclasses to call super, which lets the base class change over time.
This commit is contained in:
parent
4ab34229fb
commit
a6f8ebf33d
|
@ -456,8 +456,6 @@ public abstract class MultiChildLoadBalancer extends LoadBalancer {
|
||||||
/**
|
/**
|
||||||
* Update current state and picker for this child and then use
|
* Update current state and picker for this child and then use
|
||||||
* {@link #updateOverallBalancingState()} for the parent LB.
|
* {@link #updateOverallBalancingState()} for the parent LB.
|
||||||
*
|
|
||||||
* <p/>Override this if you don't want to automatically request a connection when in IDLE
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateBalancingState(final ConnectivityState newState,
|
public void updateBalancingState(final ConnectivityState newState,
|
||||||
|
@ -471,9 +469,6 @@ public abstract class MultiChildLoadBalancer extends LoadBalancer {
|
||||||
// If we are already in the process of resolving addresses, the overall balancing state
|
// If we are already in the process of resolving addresses, the overall balancing state
|
||||||
// will be updated at the end of it, and we don't need to trigger that update here.
|
// will be updated at the end of it, and we don't need to trigger that update here.
|
||||||
if (!resolvingAddresses) {
|
if (!resolvingAddresses) {
|
||||||
if (newState == IDLE) {
|
|
||||||
lb.requestConnection();
|
|
||||||
}
|
|
||||||
updateOverallBalancingState();
|
updateOverallBalancingState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,25 @@ final class RoundRobinLoadBalancer extends MultiChildLoadBalancer {
|
||||||
return new ReadyPicker(pickerList, sequence);
|
return new ReadyPicker(pickerList, sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChildLbState createChildLbState(Object key, Object policyConfig,
|
||||||
|
SubchannelPicker initialPicker, ResolvedAddresses resolvedAddresses) {
|
||||||
|
return new ChildLbState(key, pickFirstLbProvider, policyConfig, initialPicker) {
|
||||||
|
@Override
|
||||||
|
protected ChildLbStateHelper createChildHelper() {
|
||||||
|
return new ChildLbStateHelper() {
|
||||||
|
@Override
|
||||||
|
public void updateBalancingState(ConnectivityState newState, SubchannelPicker newPicker) {
|
||||||
|
super.updateBalancingState(newState, newPicker);
|
||||||
|
if (!resolvingAddresses && newState == IDLE) {
|
||||||
|
getLb().requestConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class ReadyPicker extends SubchannelPicker {
|
static class ReadyPicker extends SubchannelPicker {
|
||||||
private final List<SubchannelPicker> subchannelPickers; // non-empty
|
private final List<SubchannelPicker> subchannelPickers; // non-empty
|
||||||
|
|
|
@ -328,5 +328,18 @@ final class LeastRequestLoadBalancer extends MultiChildLoadBalancer {
|
||||||
int getActiveRequests() {
|
int getActiveRequests() {
|
||||||
return activeRequests.get();
|
return activeRequests.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChildLbStateHelper createChildHelper() {
|
||||||
|
return new ChildLbStateHelper() {
|
||||||
|
@Override
|
||||||
|
public void updateBalancingState(ConnectivityState newState, SubchannelPicker newPicker) {
|
||||||
|
super.updateBalancingState(newState, newPicker);
|
||||||
|
if (!resolvingAddresses && newState == IDLE) {
|
||||||
|
getLb().requestConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,7 +229,7 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
@Override
|
@Override
|
||||||
protected ChildLbState createChildLbState(Object key, Object policyConfig,
|
protected ChildLbState createChildLbState(Object key, Object policyConfig,
|
||||||
SubchannelPicker initialPicker, ResolvedAddresses resolvedAddresses) {
|
SubchannelPicker initialPicker, ResolvedAddresses resolvedAddresses) {
|
||||||
return new RingHashChildLbState((Endpoint)key);
|
return new ChildLbState(key, lazyLbFactory, null, EMPTY_PICKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Status validateAddrList(List<EquivalentAddressGroup> addrList) {
|
private Status validateAddrList(List<EquivalentAddressGroup> addrList) {
|
||||||
|
@ -358,7 +358,7 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
this.ring = ring;
|
this.ring = ring;
|
||||||
pickableSubchannels = new HashMap<>(subchannels.size());
|
pickableSubchannels = new HashMap<>(subchannels.size());
|
||||||
for (Map.Entry<Object, ChildLbState> entry : subchannels.entrySet()) {
|
for (Map.Entry<Object, ChildLbState> entry : subchannels.entrySet()) {
|
||||||
RingHashChildLbState childLbState = (RingHashChildLbState) entry.getValue();
|
ChildLbState childLbState = entry.getValue();
|
||||||
pickableSubchannels.put((Endpoint)entry.getKey(),
|
pickableSubchannels.put((Endpoint)entry.getKey(),
|
||||||
new SubchannelView(childLbState, childLbState.getCurrentState()));
|
new SubchannelView(childLbState, childLbState.getCurrentState()));
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
for (int i = 0; i < ring.size(); i++) {
|
for (int i = 0; i < ring.size(); i++) {
|
||||||
int index = (targetIndex + i) % ring.size();
|
int index = (targetIndex + i) % ring.size();
|
||||||
SubchannelView subchannelView = pickableSubchannels.get(ring.get(index).addrKey);
|
SubchannelView subchannelView = pickableSubchannels.get(ring.get(index).addrKey);
|
||||||
RingHashChildLbState childLbState = subchannelView.childLbState;
|
ChildLbState childLbState = subchannelView.childLbState;
|
||||||
|
|
||||||
if (subchannelView.connectivityState == READY) {
|
if (subchannelView.connectivityState == READY) {
|
||||||
return childLbState.getCurrentPicker().pickSubchannel(args);
|
return childLbState.getCurrentPicker().pickSubchannel(args);
|
||||||
|
@ -427,7 +427,7 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the pick from the original subchannel hit by hash, which is probably an error
|
// return the pick from the original subchannel hit by hash, which is probably an error
|
||||||
RingHashChildLbState originalSubchannel =
|
ChildLbState originalSubchannel =
|
||||||
pickableSubchannels.get(ring.get(targetIndex).addrKey).childLbState;
|
pickableSubchannels.get(ring.get(targetIndex).addrKey).childLbState;
|
||||||
return originalSubchannel.getCurrentPicker().pickSubchannel(args);
|
return originalSubchannel.getCurrentPicker().pickSubchannel(args);
|
||||||
}
|
}
|
||||||
|
@ -439,10 +439,10 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
* state changes.
|
* state changes.
|
||||||
*/
|
*/
|
||||||
private static final class SubchannelView {
|
private static final class SubchannelView {
|
||||||
private final RingHashChildLbState childLbState;
|
private final ChildLbState childLbState;
|
||||||
private final ConnectivityState connectivityState;
|
private final ConnectivityState connectivityState;
|
||||||
|
|
||||||
private SubchannelView(RingHashChildLbState childLbState, ConnectivityState state) {
|
private SubchannelView(ChildLbState childLbState, ConnectivityState state) {
|
||||||
this.childLbState = childLbState;
|
this.childLbState = childLbState;
|
||||||
this.connectivityState = state;
|
this.connectivityState = state;
|
||||||
}
|
}
|
||||||
|
@ -487,41 +487,4 @@ final class RingHashLoadBalancer extends MultiChildLoadBalancer {
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RingHashChildLbState extends MultiChildLoadBalancer.ChildLbState {
|
|
||||||
|
|
||||||
public RingHashChildLbState(Endpoint key) {
|
|
||||||
super(key, lazyLbFactory, null, EMPTY_PICKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ChildLbStateHelper createChildHelper() {
|
|
||||||
return new RingHashChildHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to expose this to the LB class
|
|
||||||
@Override
|
|
||||||
protected void shutdown() {
|
|
||||||
super.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RingHashChildHelper extends ChildLbStateHelper {
|
|
||||||
@Override
|
|
||||||
public void updateBalancingState(final ConnectivityState newState,
|
|
||||||
final SubchannelPicker newPicker) {
|
|
||||||
setCurrentState(newState);
|
|
||||||
setCurrentPicker(newPicker);
|
|
||||||
|
|
||||||
if (getChildLbState(getKey()) == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are already in the process of resolving addresses, the overall balancing state
|
|
||||||
// will be updated at the end of it, and we don't need to trigger that update here.
|
|
||||||
if (!resolvingAddresses) {
|
|
||||||
updateOverallBalancingState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,6 +340,14 @@ final class WeightedRoundRobinLoadBalancer extends MultiChildLoadBalancer {
|
||||||
public Subchannel createSubchannel(CreateSubchannelArgs args) {
|
public Subchannel createSubchannel(CreateSubchannelArgs args) {
|
||||||
return new WrrSubchannel(super.createSubchannel(args), WeightedChildLbState.this);
|
return new WrrSubchannel(super.createSubchannel(args), WeightedChildLbState.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBalancingState(ConnectivityState newState, SubchannelPicker newPicker) {
|
||||||
|
super.updateBalancingState(newState, newPicker);
|
||||||
|
if (!resolvingAddresses && newState == ConnectivityState.IDLE) {
|
||||||
|
getLb().requestConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class OrcaReportListener implements OrcaPerRequestReportListener, OrcaOobReportListener {
|
final class OrcaReportListener implements OrcaPerRequestReportListener, OrcaOobReportListener {
|
||||||
|
|
|
@ -66,7 +66,6 @@ import io.grpc.internal.PickSubchannelArgsImpl;
|
||||||
import io.grpc.testing.TestMethodDescriptors;
|
import io.grpc.testing.TestMethodDescriptors;
|
||||||
import io.grpc.util.AbstractTestHelper;
|
import io.grpc.util.AbstractTestHelper;
|
||||||
import io.grpc.util.MultiChildLoadBalancer.ChildLbState;
|
import io.grpc.util.MultiChildLoadBalancer.ChildLbState;
|
||||||
import io.grpc.xds.RingHashLoadBalancer.RingHashChildLbState;
|
|
||||||
import io.grpc.xds.RingHashLoadBalancer.RingHashConfig;
|
import io.grpc.xds.RingHashLoadBalancer.RingHashConfig;
|
||||||
import java.lang.Thread.UncaughtExceptionHandler;
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
@ -177,8 +176,7 @@ public class RingHashLoadBalancerTest {
|
||||||
assertThat(addressesAcceptanceStatus.isOk()).isTrue();
|
assertThat(addressesAcceptanceStatus.isOk()).isTrue();
|
||||||
verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
|
verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
|
||||||
|
|
||||||
RingHashChildLbState childLbState =
|
ChildLbState childLbState = loadBalancer.getChildLbStates().iterator().next();
|
||||||
(RingHashChildLbState) loadBalancer.getChildLbStates().iterator().next();
|
|
||||||
assertThat(subchannels.get(Collections.singletonList(childLbState.getEag()))).isNull();
|
assertThat(subchannels.get(Collections.singletonList(childLbState.getEag()))).isNull();
|
||||||
|
|
||||||
// Picking subchannel triggers connection.
|
// Picking subchannel triggers connection.
|
||||||
|
@ -422,7 +420,7 @@ public class RingHashLoadBalancerTest {
|
||||||
assertThat(addressesAcceptanceStatus.isOk()).isTrue();
|
assertThat(addressesAcceptanceStatus.isOk()).isTrue();
|
||||||
|
|
||||||
// Create subchannel for the first address
|
// Create subchannel for the first address
|
||||||
((RingHashChildLbState) loadBalancer.getChildLbStateEag(servers.get(0))).getCurrentPicker()
|
loadBalancer.getChildLbStateEag(servers.get(0)).getCurrentPicker()
|
||||||
.pickSubchannel(getDefaultPickSubchannelArgs(hashFunc.hashVoid()));
|
.pickSubchannel(getDefaultPickSubchannelArgs(hashFunc.hashVoid()));
|
||||||
verifyConnection(1);
|
verifyConnection(1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue