mirror of https://github.com/grpc/grpc-java.git
Eds weight allowed between max signed and max unsigned int (#9765)
* Enforce individual weights and sum of weights not exceeding the max unsigned int value
This commit is contained in:
parent
7c73baa450
commit
fe19152108
|
@ -27,6 +27,7 @@ import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
|
|||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.ConnectivityState;
|
||||
import io.grpc.ConnectivityStateInfo;
|
||||
|
@ -84,11 +85,10 @@ final class RingHashLoadBalancer extends LoadBalancer {
|
|||
public boolean acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
|
||||
logger.log(XdsLogLevel.DEBUG, "Received resolution result: {0}", resolvedAddresses);
|
||||
List<EquivalentAddressGroup> addrList = resolvedAddresses.getAddresses();
|
||||
if (addrList.isEmpty()) {
|
||||
handleNameResolutionError(Status.UNAVAILABLE.withDescription("Ring hash lb error: EDS "
|
||||
+ "resolution was successful, but returned server addresses are empty."));
|
||||
if (!validateAddrList(addrList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<EquivalentAddressGroup, EquivalentAddressGroup> latestAddrs = stripAttrs(addrList);
|
||||
Set<EquivalentAddressGroup> removedAddrs =
|
||||
Sets.newHashSet(Sets.difference(subchannels.keySet(), latestAddrs.keySet()));
|
||||
|
@ -166,6 +166,47 @@ final class RingHashLoadBalancer extends LoadBalancer {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean validateAddrList(List<EquivalentAddressGroup> addrList) {
|
||||
if (addrList.isEmpty()) {
|
||||
handleNameResolutionError(Status.UNAVAILABLE.withDescription("Ring hash lb error: EDS "
|
||||
+ "resolution was successful, but returned server addresses are empty."));
|
||||
return false;
|
||||
}
|
||||
|
||||
long totalWeight = 0;
|
||||
for (EquivalentAddressGroup eag : addrList) {
|
||||
Long weight = eag.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT);
|
||||
|
||||
if (weight == null) {
|
||||
weight = 1L;
|
||||
}
|
||||
|
||||
if (weight < 0) {
|
||||
handleNameResolutionError(Status.UNAVAILABLE.withDescription(
|
||||
String.format("Ring hash lb error: EDS resolution was successful, but returned a "
|
||||
+ "negative weight for %s.", stripAttrs(eag))));
|
||||
return false;
|
||||
}
|
||||
if (weight > UnsignedInteger.MAX_VALUE.longValue()) {
|
||||
handleNameResolutionError(Status.UNAVAILABLE.withDescription(
|
||||
String.format("Ring hash lb error: EDS resolution was successful, but returned a weight"
|
||||
+ " too large to fit in an unsigned int for %s.", stripAttrs(eag))));
|
||||
return false;
|
||||
}
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
if (totalWeight > UnsignedInteger.MAX_VALUE.longValue()) {
|
||||
handleNameResolutionError(Status.UNAVAILABLE.withDescription(
|
||||
String.format(
|
||||
"Ring hash lb error: EDS resolution was successful, but returned a sum of weights too"
|
||||
+ " large to fit in an unsigned int (%d).", totalWeight)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<RingEntry> buildRing(
|
||||
Map<EquivalentAddressGroup, Long> serverWeights, long totalWeight, double scale) {
|
||||
List<RingEntry> ring = new ArrayList<>();
|
||||
|
|
|
@ -36,6 +36,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.ConnectivityStateInfo;
|
||||
|
@ -961,6 +962,46 @@ public class RingHashLoadBalancerTest {
|
|||
.requestConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void largeWeights() {
|
||||
RingHashConfig config = new RingHashConfig(10000, 100000); // large ring
|
||||
List<EquivalentAddressGroup> servers =
|
||||
createWeightedServerAddrs(Integer.MAX_VALUE, 10, 100); // MAX:10:100
|
||||
boolean addressesAccepted = loadBalancer.acceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
|
||||
assertThat(addressesAccepted).isTrue();
|
||||
|
||||
// Try value between max signed and max unsigned int
|
||||
servers = createWeightedServerAddrs(Integer.MAX_VALUE + 100L, 100); // (MAX+100):100
|
||||
addressesAccepted = loadBalancer.acceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
|
||||
assertThat(addressesAccepted).isTrue();
|
||||
|
||||
// Try a negative value
|
||||
servers = createWeightedServerAddrs(10, -20, 100); // 10:-20:100
|
||||
addressesAccepted = loadBalancer.acceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
|
||||
assertThat(addressesAccepted).isFalse();
|
||||
|
||||
// Try an individual value larger than max unsigned int
|
||||
long maxUnsigned = UnsignedInteger.MAX_VALUE.longValue();
|
||||
servers = createWeightedServerAddrs(maxUnsigned + 10, 10, 100); // uMAX+10:10:100
|
||||
addressesAccepted = loadBalancer.acceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
|
||||
assertThat(addressesAccepted).isFalse();
|
||||
|
||||
// Try a sum of values larger than max unsigned int
|
||||
servers = createWeightedServerAddrs(Integer.MAX_VALUE, Integer.MAX_VALUE, 100); // MAX:MAX:100
|
||||
addressesAccepted = loadBalancer.acceptResolvedAddresses(
|
||||
ResolvedAddresses.newBuilder()
|
||||
.setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
|
||||
assertThat(addressesAccepted).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hostSelectionProportionalToWeights() {
|
||||
RingHashConfig config = new RingHashConfig(10000, 100000); // large ring
|
||||
|
|
Loading…
Reference in New Issue