Search in sources :

Example 1 with PickSubchannelArgsImpl

use of io.grpc.internal.PickSubchannelArgsImpl 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));
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) PickSubchannelArgsImpl(io.grpc.internal.PickSubchannelArgsImpl) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) 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 2 with PickSubchannelArgsImpl

use of io.grpc.internal.PickSubchannelArgsImpl 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);
}
Also used : InOrder(org.mockito.InOrder) 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 3 with PickSubchannelArgsImpl

use of io.grpc.internal.PickSubchannelArgsImpl 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 4 with PickSubchannelArgsImpl

use of io.grpc.internal.PickSubchannelArgsImpl 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 5 with PickSubchannelArgsImpl

use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.

the class RlsLoadBalancerTest method lb_working_withoutDefaultTarget.

@Test
public void lb_working_withoutDefaultTarget() throws Exception {
    defaultTarget = "";
    deliverResolvedAddresses();
    InOrder inOrder = inOrder(helper);
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
    SubchannelPicker picker = pickerCaptor.getValue();
    Metadata headers = new Metadata();
    PickResult res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
    inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
    inOrder.verifyNoMoreInteractions();
    assertThat(res.getStatus().isOk()).isTrue();
    assertThat(subchannels).hasSize(1);
    FakeSubchannel searchSubchannel = subchannels.getLast();
    searchSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
    inOrder.verifyNoMoreInteractions();
    assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
    assertThat(res.getSubchannel().getAddresses()).isEqualTo(searchSubchannel.getAddresses());
    assertThat(res.getSubchannel().getAttributes()).isEqualTo(searchSubchannel.getAttributes());
    // rescue should be pending status although the overall channel state is READY
    picker = pickerCaptor.getValue();
    res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
    inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
    // other rls picker itself is ready due to first channel.
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
    inOrder.verifyNoMoreInteractions();
    assertThat(res.getStatus().isOk()).isTrue();
    assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
    assertThat(subchannels).hasSize(2);
    FakeSubchannel rescueSubchannel = subchannels.getLast();
    // search subchannel is down, rescue subchannel is still connecting
    searchSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
    rescueSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
    // search method will fail because there is no fallback target.
    picker = pickerCaptor.getValue();
    res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
    assertThat(res.getStatus().isOk()).isFalse();
    assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
    res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
    assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
    assertThat(res.getSubchannel().getAddresses()).isEqualTo(rescueSubchannel.getAddresses());
    assertThat(res.getSubchannel().getAttributes()).isEqualTo(rescueSubchannel.getAttributes());
    // all channels are failed
    rescueSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
    inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
    inOrder.verifyNoMoreInteractions();
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) InOrder(org.mockito.InOrder) PickSubchannelArgsImpl(io.grpc.internal.PickSubchannelArgsImpl) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) Metadata(io.grpc.Metadata) PickResult(io.grpc.LoadBalancer.PickResult) Test(org.junit.Test)

Aggregations

Metadata (io.grpc.Metadata)20 PickSubchannelArgsImpl (io.grpc.internal.PickSubchannelArgsImpl)20 Test (org.junit.Test)17 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)13 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)12 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)10 PickResult (io.grpc.LoadBalancer.PickResult)10 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)10 RingHashConfig (io.grpc.xds.RingHashLoadBalancer.RingHashConfig)10 Subchannel (io.grpc.LoadBalancer.Subchannel)7 InOrder (org.mockito.InOrder)7 Result (io.grpc.InternalConfigSelector.Result)6 ResolutionResult (io.grpc.NameResolver.ResolutionResult)6 InternalConfigSelector (io.grpc.InternalConfigSelector)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ClientInterceptor (io.grpc.ClientInterceptor)2 Status (io.grpc.Status)2 HashPolicy (io.grpc.xds.VirtualHost.Route.RouteAction.HashPolicy)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2