Search in sources :

Example 6 with RingHashConfig

use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.

the class RingHashLoadBalancerTest method allSubchannelsInTransientFailure.

@Test
public void allSubchannelsInTransientFailure() {
    // 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));
    verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
    // Bring all subchannels to TRANSIENT_FAILURE.
    for (Subchannel subchannel : subchannels.values()) {
        deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription(subchannel.getAddresses().getAddresses() + " unreachable")));
    }
    verify(helper, atLeastOnce()).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
    // Picking subchannel triggers connection. RPC hash hits server0.
    PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, hashFunc.hashVoid()));
    PickResult result = pickerCaptor.getValue().pickSubchannel(args);
    assertThat(result.getStatus().isOk()).isFalse();
    assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
    assertThat(result.getStatus().getDescription()).isEqualTo("[FakeSocketAddress-server0] unreachable");
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) PickSubchannelArgsImpl(io.grpc.internal.PickSubchannelArgsImpl) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) Metadata(io.grpc.Metadata) PickResult(io.grpc.LoadBalancer.PickResult) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 7 with RingHashConfig

use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.

the class RingHashLoadBalancerTest method ignoreShutdownSubchannelStateChange.

@Test
public void ignoreShutdownSubchannelStateChange() {
    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));
    loadBalancer.shutdown();
    for (Subchannel sc : subchannels.values()) {
        verify(sc).shutdown();
        // When the subchannel is being shut down, a SHUTDOWN connectivity state is delivered
        // back to the subchannel state listener.
        deliverSubchannelState(sc, ConnectivityStateInfo.forNonError(SHUTDOWN));
    }
    verifyNoMoreInteractions(helper);
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) Test(org.junit.Test)

Example 8 with RingHashConfig

use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.

the class RingHashLoadBalancerTest method hostSelectionProportionalToRepeatedAddressCount.

@Test
public void hostSelectionProportionalToRepeatedAddressCount() {
    RingHashConfig config = new RingHashConfig(10000, 100000);
    // 1:10:100
    List<EquivalentAddressGroup> servers = createRepeatedServerAddrs(1, 10, 100);
    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));
    // Bring all subchannels to READY.
    Map<EquivalentAddressGroup, Integer> pickCounts = new HashMap<>();
    for (Subchannel subchannel : subchannels.values()) {
        deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
        pickCounts.put(subchannel.getAddresses(), 0);
    }
    verify(helper, times(3)).updateBalancingState(eq(READY), pickerCaptor.capture());
    SubchannelPicker picker = pickerCaptor.getValue();
    for (int i = 0; i < 10000; i++) {
        long hash = hashFunc.hashInt(i);
        PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, hash));
        Subchannel pickedSubchannel = picker.pickSubchannel(args).getSubchannel();
        EquivalentAddressGroup addr = pickedSubchannel.getAddresses();
        pickCounts.put(addr, pickCounts.get(addr) + 1);
    }
    // Actual distribution: server0 = 104, server1 = 808, server2 = 9088
    double ratio01 = (double) pickCounts.get(servers.get(0)) / pickCounts.get(servers.get(1));
    double ratio12 = (double) pickCounts.get(servers.get(1)) / pickCounts.get(servers.get(11));
    assertThat(ratio01).isWithin(0.03).of((double) 1 / 10);
    assertThat(ratio12).isWithin(0.03).of((double) 10 / 100);
}
Also used : HashMap(java.util.HashMap) Metadata(io.grpc.Metadata) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) PickSubchannelArgsImpl(io.grpc.internal.PickSubchannelArgsImpl) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 9 with RingHashConfig

use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.

the class CdsLoadBalancer2Test method discoverAggregateCluster.

@Test
public void discoverAggregateCluster() {
    String cluster1 = "cluster-01.googleapis.com";
    String cluster2 = "cluster-02.googleapis.com";
    // CLUSTER (aggr.) -> [cluster1 (aggr.), cluster2 (logical DNS)]
    CdsUpdate update = CdsUpdate.forAggregate(CLUSTER, Arrays.asList(cluster1, cluster2)).ringHashLbPolicy(100L, 1000L).build();
    xdsClient.deliverCdsUpdate(CLUSTER, update);
    assertThat(xdsClient.watchers.keySet()).containsExactly(CLUSTER, cluster1, cluster2);
    assertThat(childBalancers).isEmpty();
    String cluster3 = "cluster-03.googleapis.com";
    String cluster4 = "cluster-04.googleapis.com";
    // cluster1 (aggr.) -> [cluster3 (EDS), cluster4 (EDS)]
    CdsUpdate update1 = CdsUpdate.forAggregate(cluster1, Arrays.asList(cluster3, cluster4)).roundRobinLbPolicy().build();
    xdsClient.deliverCdsUpdate(cluster1, update1);
    assertThat(xdsClient.watchers.keySet()).containsExactly(CLUSTER, cluster1, cluster2, cluster3, cluster4);
    assertThat(childBalancers).isEmpty();
    CdsUpdate update3 = CdsUpdate.forEds(cluster3, EDS_SERVICE_NAME, LRS_SERVER_INFO, 200L, upstreamTlsContext).roundRobinLbPolicy().build();
    xdsClient.deliverCdsUpdate(cluster3, update3);
    assertThat(childBalancers).isEmpty();
    CdsUpdate update2 = CdsUpdate.forLogicalDns(cluster2, DNS_HOST_NAME, null, 100L, null).roundRobinLbPolicy().build();
    xdsClient.deliverCdsUpdate(cluster2, update2);
    assertThat(childBalancers).isEmpty();
    CdsUpdate update4 = CdsUpdate.forEds(cluster4, null, LRS_SERVER_INFO, 300L, null).roundRobinLbPolicy().build();
    xdsClient.deliverCdsUpdate(cluster4, update4);
    // all non-aggregate clusters discovered
    assertThat(childBalancers).hasSize(1);
    FakeLoadBalancer childBalancer = Iterables.getOnlyElement(childBalancers);
    assertThat(childBalancer.name).isEqualTo(CLUSTER_RESOLVER_POLICY_NAME);
    ClusterResolverConfig childLbConfig = (ClusterResolverConfig) childBalancer.config;
    assertThat(childLbConfig.discoveryMechanisms).hasSize(3);
    // Clusters on higher level has higher priority: [cluster2, cluster3, cluster4]
    assertDiscoveryMechanism(childLbConfig.discoveryMechanisms.get(0), cluster2, DiscoveryMechanism.Type.LOGICAL_DNS, null, DNS_HOST_NAME, null, 100L, null);
    assertDiscoveryMechanism(childLbConfig.discoveryMechanisms.get(1), cluster3, DiscoveryMechanism.Type.EDS, EDS_SERVICE_NAME, null, LRS_SERVER_INFO, 200L, upstreamTlsContext);
    assertDiscoveryMechanism(childLbConfig.discoveryMechanisms.get(2), cluster4, DiscoveryMechanism.Type.EDS, null, null, LRS_SERVER_INFO, 300L, null);
    assertThat(childLbConfig.lbPolicy.getProvider().getPolicyName()).isEqualTo(// dominated by top-level cluster's config
    "ring_hash_experimental");
    assertThat(((RingHashConfig) childLbConfig.lbPolicy.getConfig()).minRingSize).isEqualTo(100L);
    assertThat(((RingHashConfig) childLbConfig.lbPolicy.getConfig()).maxRingSize).isEqualTo(1000L);
}
Also used : ClusterResolverConfig(io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) CdsUpdate(io.grpc.xds.XdsClient.CdsUpdate) Test(org.junit.Test)

Example 10 with RingHashConfig

use of io.grpc.xds.RingHashLoadBalancer.RingHashConfig in project grpc-java by grpc.

the class RingHashLoadBalancerTest method aggregateSubchannelStates_twoOrMoreSubchannelsInTransientFailure.

@Test
public void aggregateSubchannelStates_twoOrMoreSubchannelsInTransientFailure() {
    RingHashConfig config = new RingHashConfig(10, 100);
    List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1, 1, 1, 1);
    InOrder inOrder = Mockito.inOrder(helper);
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
    inOrder.verify(helper, times(4)).createSubchannel(any(CreateSubchannelArgs.class));
    inOrder.verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
    // one in TRANSIENT_FAILURE, three in IDLE
    deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(0))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("not found")));
    inOrder.verify(helper).refreshNameResolution();
    inOrder.verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
    // two in TRANSIENT_FAILURE, two in IDLE
    deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(1))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("also not found")));
    inOrder.verify(helper).refreshNameResolution();
    inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), any(SubchannelPicker.class));
    // two in TRANSIENT_FAILURE, one in CONNECTING, one in IDLE
    // The overall state is dominated by the two in TRANSIENT_FAILURE.
    deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(CONNECTING));
    inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), any(SubchannelPicker.class));
    // three in TRANSIENT_FAILURE, one in CONNECTING
    deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(3))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("connection lost")));
    inOrder.verify(helper).refreshNameResolution();
    inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), any(SubchannelPicker.class));
    // three in TRANSIENT_FAILURE, one in READY
    deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(helper).updateBalancingState(eq(READY), any(SubchannelPicker.class));
    verifyNoMoreInteractions(helper);
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) InOrder(org.mockito.InOrder) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) Test(org.junit.Test)

Aggregations

RingHashConfig (io.grpc.xds.RingHashLoadBalancer.RingHashConfig)19 Test (org.junit.Test)18 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)15 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)13 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)13 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)10 Metadata (io.grpc.Metadata)10 PickSubchannelArgsImpl (io.grpc.internal.PickSubchannelArgsImpl)10 Subchannel (io.grpc.LoadBalancer.Subchannel)9 PickResult (io.grpc.LoadBalancer.PickResult)6 InOrder (org.mockito.InOrder)5 ConfigOrError (io.grpc.NameResolver.ConfigOrError)2 ClusterResolverConfig (io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig)2 HashMap (java.util.HashMap)2 Attributes (io.grpc.Attributes)1 ClusterImplConfig (io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig)1 LocalityLbEndpoints (io.grpc.xds.Endpoints.LocalityLbEndpoints)1 PriorityLbConfig (io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig)1 PriorityChildConfig (io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig)1 CdsUpdate (io.grpc.xds.XdsClient.CdsUpdate)1