Search in sources :

Example 21 with PickSubchannelArgs

use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.

the class RingHashLoadBalancerTest method hostSelectionProportionalToWeights.

@Test
public void hostSelectionProportionalToWeights() {
    // large ring
    RingHashConfig config = new RingHashConfig(10000, 100000);
    // 1:10:100
    List<EquivalentAddressGroup> servers = createWeightedServerAddrs(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(2));
    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 22 with PickSubchannelArgs

use of io.grpc.LoadBalancer.PickSubchannelArgs 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();
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) InOrder(org.mockito.InOrder) PickSubchannelArgsImpl(io.grpc.internal.PickSubchannelArgsImpl) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) Metadata(io.grpc.Metadata) RingHashConfig(io.grpc.xds.RingHashLoadBalancer.RingHashConfig) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 23 with PickSubchannelArgs

use of io.grpc.LoadBalancer.PickSubchannelArgs 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));
}
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 24 with PickSubchannelArgs

use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.

the class PriorityLoadBalancerTest method readyToConnectDoesNotFailOverButUpdatesPicker.

@Test
public void readyToConnectDoesNotFailOverButUpdatesPicker() {
    PriorityChildConfig priorityChildConfig0 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
    PriorityChildConfig priorityChildConfig1 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
    PriorityLbConfig priorityLbConfig = new PriorityLbConfig(ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1), ImmutableList.of("p0", "p1"));
    priorityLb.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(ImmutableList.<EquivalentAddressGroup>of()).setLoadBalancingPolicyConfig(priorityLbConfig).build());
    assertThat(fooBalancers).hasSize(1);
    assertThat(fooHelpers).hasSize(1);
    Helper helper0 = Iterables.getOnlyElement(fooHelpers);
    // p0 gets READY.
    final Subchannel subchannel0 = mock(Subchannel.class);
    helper0.updateBalancingState(READY, new SubchannelPicker() {

        @Override
        public PickResult pickSubchannel(PickSubchannelArgs args) {
            return PickResult.withSubchannel(subchannel0);
        }
    });
    assertCurrentPickerPicksSubchannel(subchannel0);
    // p0 goes to CONNECTING
    helper0.updateBalancingState(IDLE, BUFFER_PICKER);
    assertCurrentPickerIsBufferPicker();
    // no failover happened
    assertThat(fooBalancers).hasSize(1);
    assertThat(fooHelpers).hasSize(1);
    // resolution update without priority change does not trigger failover
    Attributes.Key<String> fooKey = Attributes.Key.create("fooKey");
    priorityLb.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(ImmutableList.<EquivalentAddressGroup>of()).setLoadBalancingPolicyConfig(priorityLbConfig).setAttributes(Attributes.newBuilder().set(fooKey, "barVal").build()).build());
    assertCurrentPickerIsBufferPicker();
    // no failover happened
    assertThat(fooBalancers).hasSize(1);
    assertThat(fooHelpers).hasSize(1);
}
Also used : PriorityChildConfig(io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig) PriorityLbConfig(io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig) Attributes(io.grpc.Attributes) PolicySelection(io.grpc.internal.ServiceConfigUtil.PolicySelection) Helper(io.grpc.LoadBalancer.Helper) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 25 with PickSubchannelArgs

use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.

the class ConfigSelectingClientCallTest method configSelectorInterceptsCall.

@Test
public void configSelectorInterceptsCall() {
    Map<String, ?> rawMethodConfig = ImmutableMap.of("retryPolicy", ImmutableMap.of("maxAttempts", 3.0D, "initialBackoff", "1s", "maxBackoff", "10s", "backoffMultiplier", 1.5D, "retryableStatusCodes", ImmutableList.of("UNAVAILABLE")));
    final MethodInfo methodInfo = new MethodInfo(rawMethodConfig, true, 4, 4);
    final Metadata.Key<String> metadataKey = Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER);
    final CallOptions.Key<String> callOptionsKey = CallOptions.Key.create("test");
    InternalConfigSelector configSelector = new InternalConfigSelector() {

        @Override
        public Result selectConfig(final PickSubchannelArgs args) {
            ManagedChannelServiceConfig config = new ManagedChannelServiceConfig(methodInfo, ImmutableMap.<String, MethodInfo>of(), ImmutableMap.<String, MethodInfo>of(), null, null, null);
            return Result.newBuilder().setConfig(config).setInterceptor(// An interceptor that mutates CallOptions based on headers value.
            new ClientInterceptor() {

                String value = args.getHeaders().get(metadataKey);

                @Override
                public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
                    callOptions = callOptions.withOption(callOptionsKey, value);
                    return next.newCall(method, callOptions);
                }
            }).build();
        }
    };
    ClientCall<Void, Void> configSelectingClientCall = new ConfigSelectingClientCall<>(configSelector, channel, MoreExecutors.directExecutor(), method, CallOptions.DEFAULT.withAuthority("bar.authority"));
    Metadata metadata = new Metadata();
    metadata.put(metadataKey, "fooValue");
    configSelectingClientCall.start(callListener, metadata);
    assertThat(call.callOptions.getAuthority()).isEqualTo("bar.authority");
    assertThat(call.callOptions.getOption(MethodInfo.KEY)).isEqualTo(methodInfo);
    assertThat(call.callOptions.getOption(callOptionsKey)).isEqualTo("fooValue");
}
Also used : Channel(io.grpc.Channel) Metadata(io.grpc.Metadata) CallOptions(io.grpc.CallOptions) MethodDescriptor(io.grpc.MethodDescriptor) InternalConfigSelector(io.grpc.InternalConfigSelector) ClientInterceptor(io.grpc.ClientInterceptor) ConfigSelectingClientCall(io.grpc.internal.ManagedChannelImpl.ConfigSelectingClientCall) MethodInfo(io.grpc.internal.ManagedChannelServiceConfig.MethodInfo) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Aggregations

PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)30 Test (org.junit.Test)27 Metadata (io.grpc.Metadata)19 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)17 Subchannel (io.grpc.LoadBalancer.Subchannel)17 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)17 PickResult (io.grpc.LoadBalancer.PickResult)13 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)10 PickSubchannelArgsImpl (io.grpc.internal.PickSubchannelArgsImpl)10 RingHashConfig (io.grpc.xds.RingHashLoadBalancer.RingHashConfig)10 RoundRobinPicker (io.grpc.grpclb.GrpclbState.RoundRobinPicker)6 InOrder (org.mockito.InOrder)6 Attributes (io.grpc.Attributes)5 BackendEntry (io.grpc.grpclb.GrpclbState.BackendEntry)4 DropEntry (io.grpc.grpclb.GrpclbState.DropEntry)4 InitialLoadBalanceResponse (io.grpc.lb.v1.InitialLoadBalanceResponse)4 LoadBalanceResponse (io.grpc.lb.v1.LoadBalanceResponse)4 InternalConfigSelector (io.grpc.InternalConfigSelector)3 Helper (io.grpc.LoadBalancer.Helper)3 Status (io.grpc.Status)3