use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerTest method subchannelNotAutoReconnectAfterReenteringIdle.
@Test
public void subchannelNotAutoReconnectAfterReenteringIdle() {
RingHashConfig config = new RingHashConfig(10, 100);
// one server
List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
Subchannel subchannel = Iterables.getOnlyElement(subchannels.values());
InOrder inOrder = Mockito.inOrder(helper, subchannel);
inOrder.verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
inOrder.verify(subchannel, never()).requestConnection();
// Picking subchannel triggers connection.
PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, hashFunc.hashVoid()));
pickerCaptor.getValue().pickSubchannel(args);
inOrder.verify(subchannel).requestConnection();
deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updateBalancingState(eq(READY), any(SubchannelPicker.class));
deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(IDLE));
inOrder.verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
inOrder.verify(subchannel, never()).requestConnection();
// Picking again triggers reconnection.
pickerCaptor.getValue().pickSubchannel(args);
inOrder.verify(subchannel).requestConnection();
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerTest method skipFailingHosts_firstTwoHostsFailed_pickNextFirstReady.
@Test
public void skipFailingHosts_firstTwoHostsFailed_pickNextFirstReady() {
// Map each server address to exactly one ring entry.
RingHashConfig config = new RingHashConfig(3, 3);
List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1, 1, 1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
verify(helper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
// initial IDLE
verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
reset(helper);
// ring:
// "[FakeSocketAddress-server1]_0"
// "[FakeSocketAddress-server0]_0"
// "[FakeSocketAddress-server2]_0"
long rpcHash = hashFunc.hashAsciiString("[FakeSocketAddress-server0]_0");
PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, rpcHash));
// Bring down server0 and server2 to force trying server1.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(0))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("unreachable")));
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forTransientFailure(Status.PERMISSION_DENIED.withDescription("permission denied")));
verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
verify(subchannels.get(Collections.singletonList(servers.get(1)))).requestConnection();
PickResult result = pickerCaptor.getValue().pickSubchannel(args);
// fail the RPC
assertThat(result.getStatus().isOk()).isFalse();
assertThat(result.getStatus().getCode()).isEqualTo(// with error status for the original server hit by hash
Code.UNAVAILABLE);
assertThat(result.getStatus().getDescription()).isEqualTo("unreachable");
verify(subchannels.get(Collections.singletonList(servers.get(1))), times(2)).requestConnection();
// Now connecting to server1.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(1))), ConnectivityStateInfo.forNonError(CONNECTING));
verify(helper, times(2)).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
// fail the RPC
assertThat(result.getStatus().isOk()).isFalse();
assertThat(result.getStatus().getCode()).isEqualTo(// with error status for the original server hit by hash
Code.UNAVAILABLE);
assertThat(result.getStatus().getDescription()).isEqualTo("unreachable");
// Simulate server1 becomes READY.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(1))), ConnectivityStateInfo.forNonError(READY));
verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
// succeed
assertThat(result.getStatus().isOk()).isTrue();
// with server1
assertThat(result.getSubchannel().getAddresses()).isEqualTo(servers.get(1));
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerProviderTest method parseLoadBalancingConfig_valid.
@Test
public void parseLoadBalancingConfig_valid() throws IOException {
String lbConfig = "{\"minRingSize\" : 10, \"maxRingSize\" : 100}";
ConfigOrError configOrError = provider.parseLoadBalancingPolicyConfig(parseJsonObject(lbConfig));
assertThat(configOrError.getConfig()).isNotNull();
RingHashConfig config = (RingHashConfig) configOrError.getConfig();
assertThat(config.minRingSize).isEqualTo(10L);
assertThat(config.maxRingSize).isEqualTo(100L);
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerProvider method parseLoadBalancingPolicyConfig.
@Override
public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig) {
Long minRingSize = JsonUtil.getNumberAsLong(rawLoadBalancingPolicyConfig, "minRingSize");
Long maxRingSize = JsonUtil.getNumberAsLong(rawLoadBalancingPolicyConfig, "maxRingSize");
if (minRingSize == null) {
minRingSize = DEFAULT_MIN_RING_SIZE;
}
if (maxRingSize == null) {
maxRingSize = DEFAULT_MAX_RING_SIZE;
}
if (minRingSize <= 0 || maxRingSize <= 0 || minRingSize > maxRingSize || maxRingSize > MAX_RING_SIZE) {
return ConfigOrError.fromError(Status.INVALID_ARGUMENT.withDescription("Invalid 'mingRingSize'/'maxRingSize'"));
}
return ConfigOrError.fromConfig(new RingHashConfig(minRingSize, maxRingSize));
}
Aggregations