use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerProviderTest method parseLoadBalancingConfig_missingRingSize_useDefaults.
@Test
public void parseLoadBalancingConfig_missingRingSize_useDefaults() throws IOException {
String lbConfig = "{}";
ConfigOrError configOrError = provider.parseLoadBalancingPolicyConfig(parseJsonObject(lbConfig));
assertThat(configOrError.getConfig()).isNotNull();
RingHashConfig config = (RingHashConfig) configOrError.getConfig();
assertThat(config.minRingSize).isEqualTo(RingHashLoadBalancerProvider.DEFAULT_MIN_RING_SIZE);
assertThat(config.maxRingSize).isEqualTo(RingHashLoadBalancerProvider.DEFAULT_MAX_RING_SIZE);
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class ClusterResolverLoadBalancerTest method edsClustersWithRingHashEndpointLbPolicy.
@Test
public void edsClustersWithRingHashEndpointLbPolicy() {
ClusterResolverConfig config = new ClusterResolverConfig(Collections.singletonList(edsDiscoveryMechanism1), ringHash);
deliverLbConfig(config);
assertThat(xdsClient.watchers.keySet()).containsExactly(EDS_SERVICE_NAME1);
assertThat(childBalancers).isEmpty();
// One priority with two localities of different weights.
EquivalentAddressGroup endpoint1 = makeAddress("endpoint-addr-1");
EquivalentAddressGroup endpoint2 = makeAddress("endpoint-addr-2");
EquivalentAddressGroup endpoint3 = makeAddress("endpoint-addr-3");
LocalityLbEndpoints localityLbEndpoints1 = LocalityLbEndpoints.create(Arrays.asList(LbEndpoint.create(endpoint1, 0, /* loadBalancingWeight */
true), LbEndpoint.create(endpoint2, 0, /* loadBalancingWeight */
true)), 10, /* localityWeight */
1);
LocalityLbEndpoints localityLbEndpoints2 = LocalityLbEndpoints.create(Collections.singletonList(LbEndpoint.create(endpoint3, 60, /* loadBalancingWeight */
true)), 50, /* localityWeight */
1);
xdsClient.deliverClusterLoadAssignment(EDS_SERVICE_NAME1, ImmutableMap.of(locality1, localityLbEndpoints1, locality2, localityLbEndpoints2));
assertThat(childBalancers).hasSize(1);
FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
assertThat(childBalancer.addresses).hasSize(3);
EquivalentAddressGroup addr1 = childBalancer.addresses.get(0);
EquivalentAddressGroup addr2 = childBalancer.addresses.get(1);
EquivalentAddressGroup addr3 = childBalancer.addresses.get(2);
// Endpoints in locality1 have no endpoint-level weight specified, so all endpoints within
// locality1 are equally weighted.
assertThat(addr1.getAddresses()).isEqualTo(endpoint1.getAddresses());
assertThat(addr1.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT)).isEqualTo(10);
assertThat(addr2.getAddresses()).isEqualTo(endpoint2.getAddresses());
assertThat(addr2.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT)).isEqualTo(10);
assertThat(addr3.getAddresses()).isEqualTo(endpoint3.getAddresses());
assertThat(addr3.getAttributes().get(InternalXdsAttributes.ATTR_SERVER_WEIGHT)).isEqualTo(50 * 60);
assertThat(childBalancer.name).isEqualTo(PRIORITY_POLICY_NAME);
PriorityLbConfig priorityLbConfig = (PriorityLbConfig) childBalancer.config;
assertThat(priorityLbConfig.priorities).containsExactly(CLUSTER1 + "[priority1]");
PriorityChildConfig priorityChildConfig = Iterables.getOnlyElement(priorityLbConfig.childConfigs.values());
assertThat(priorityChildConfig.ignoreReresolution).isTrue();
assertThat(priorityChildConfig.policySelection.getProvider().getPolicyName()).isEqualTo(CLUSTER_IMPL_POLICY_NAME);
ClusterImplConfig clusterImplConfig = (ClusterImplConfig) priorityChildConfig.policySelection.getConfig();
assertClusterImplConfig(clusterImplConfig, CLUSTER1, EDS_SERVICE_NAME1, LRS_SERVER_INFO, 100L, tlsContext, Collections.<DropOverload>emptyList(), "ring_hash_experimental");
RingHashConfig ringHashConfig = (RingHashConfig) clusterImplConfig.childPolicy.getConfig();
assertThat(ringHashConfig.minRingSize).isEqualTo(10L);
assertThat(ringHashConfig.maxRingSize).isEqualTo(100L);
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerTest method subchannelStayInTransientFailureUntilBecomeReady.
@Test
public void subchannelStayInTransientFailureUntilBecomeReady() {
RingHashConfig config = new RingHashConfig(10, 100);
List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1, 1, 1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
verify(helper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
reset(helper);
// Simulate picks have taken place and subchannels have requested connection.
for (Subchannel subchannel : subchannels.values()) {
deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(Status.UNAUTHENTICATED.withDescription("Permission denied")));
}
verify(helper, times(3)).refreshNameResolution();
// Stays in IDLE when until there are two or more subchannels in TRANSIENT_FAILURE.
verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
verify(helper, times(2)).updateBalancingState(eq(TRANSIENT_FAILURE), any(SubchannelPicker.class));
verifyNoMoreInteractions(helper);
// Simulate underlying subchannel auto reconnect after backoff.
for (Subchannel subchannel : subchannels.values()) {
deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(CONNECTING));
}
verifyNoMoreInteractions(helper);
// Simulate one subchannel enters READY.
deliverSubchannelState(subchannels.values().iterator().next(), ConnectivityStateInfo.forNonError(READY));
verify(helper).updateBalancingState(eq(READY), any(SubchannelPicker.class));
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerTest method skipFailingHosts_pickNextNonFailingHostInFirstTwoHosts.
@Test
public void skipFailingHosts_pickNextNonFailingHostInFirstTwoHosts() {
// 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 to force trying server2.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(0))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("unreachable")));
verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
PickResult result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
// buffer request
assertThat(result.getSubchannel()).isNull();
verify(subchannels.get(Collections.singletonList(servers.get(2)))).requestConnection();
verify(subchannels.get(Collections.singletonList(servers.get(1))), never()).requestConnection();
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(CONNECTING));
verify(helper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
// buffer request
assertThat(result.getSubchannel()).isNull();
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(READY));
verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
assertThat(result.getSubchannel().getAddresses()).isEqualTo(servers.get(2));
}
use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.
the class RingHashLoadBalancerTest method deterministicPickWithNewHostsAdded.
@Test
public void deterministicPickWithNewHostsAdded() {
RingHashConfig config = new RingHashConfig(10, 100);
// server0 and server1
List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1, 1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
InOrder inOrder = Mockito.inOrder(helper);
inOrder.verify(helper, times(2)).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
// Bring all subchannels to READY so that next pick always succeeds.
for (Subchannel subchannel : subchannels.values()) {
deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
}
// Simulate rpc hash hits one ring entry exactly for server1.
long rpcHash = hashFunc.hashAsciiString("[FakeSocketAddress-server1]_0");
PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, rpcHash));
pickerCaptor.getValue().pickSubchannel(args);
PickResult result = pickerCaptor.getValue().pickSubchannel(args);
Subchannel subchannel = result.getSubchannel();
assertThat(subchannel.getAddresses()).isEqualTo(servers.get(1));
// server2, server3, server4 added
servers = createWeightedServerAddrs(1, 1, 1, 1, 1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
inOrder.verify(helper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
assertThat(pickerCaptor.getValue().pickSubchannel(args).getSubchannel()).isSameInstanceAs(subchannel);
verifyNoMoreInteractions(helper);
}
Aggregations