Search in sources :

Example 71 with Subchannel

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

the class GrpclbLoadBalancerTest method roundRobinPicker.

@Test
public void roundRobinPicker() {
    Subchannel subchannel = mock(Subchannel.class);
    RoundRobinEntry r1 = new RoundRobinEntry(Status.UNAVAILABLE.withDescription("Just error"));
    RoundRobinEntry r2 = new RoundRobinEntry(subchannel, "LBTOKEN0001");
    RoundRobinEntry r3 = new RoundRobinEntry(subchannel, "LBTOKEN0002");
    List<RoundRobinEntry> list = Arrays.asList(r1, r2, r3);
    RoundRobinPicker picker = new RoundRobinPicker(list);
    PickSubchannelArgs args1 = mock(PickSubchannelArgs.class);
    Metadata headers1 = new Metadata();
    when(args1.getHeaders()).thenReturn(headers1);
    assertSame(r1.result, picker.pickSubchannel(args1));
    verify(args1).getHeaders();
    assertFalse(headers1.containsKey(GrpclbLoadBalancer.TOKEN_KEY));
    PickSubchannelArgs args2 = mock(PickSubchannelArgs.class);
    Metadata headers2 = new Metadata();
    // The existing token on the headers will be replaced
    headers2.put(GrpclbLoadBalancer.TOKEN_KEY, "LBTOKEN__OLD");
    when(args2.getHeaders()).thenReturn(headers2);
    assertSame(r2.result, picker.pickSubchannel(args2));
    verify(args2).getHeaders();
    assertThat(headers2.getAll(GrpclbLoadBalancer.TOKEN_KEY)).containsExactly("LBTOKEN0001");
    PickSubchannelArgs args3 = mock(PickSubchannelArgs.class);
    Metadata headers3 = new Metadata();
    when(args3.getHeaders()).thenReturn(headers3);
    assertSame(r3.result, picker.pickSubchannel(args3));
    verify(args3).getHeaders();
    assertThat(headers3.getAll(GrpclbLoadBalancer.TOKEN_KEY)).containsExactly("LBTOKEN0002");
    PickSubchannelArgs args4 = mock(PickSubchannelArgs.class);
    Metadata headers4 = new Metadata();
    when(args4.getHeaders()).thenReturn(headers4);
    assertSame(r1.result, picker.pickSubchannel(args4));
    verify(args4).getHeaders();
    assertFalse(headers4.containsKey(GrpclbLoadBalancer.TOKEN_KEY));
    verify(subchannel, never()).getAttributes();
}
Also used : RoundRobinPicker(io.grpc.grpclb.GrpclbLoadBalancer.RoundRobinPicker) Subchannel(io.grpc.LoadBalancer.Subchannel) Metadata(io.grpc.Metadata) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) RoundRobinEntry(io.grpc.grpclb.GrpclbLoadBalancer.RoundRobinEntry) Test(org.junit.Test)

Example 72 with Subchannel

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

the class ManagedChannelImplIdlenessTest method updateSubchannelAddresses_newAddressConnects.

@Test
public void updateSubchannelAddresses_newAddressConnects() {
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    // Create LB
    call.start(mockCallListener, new Metadata());
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(null);
    verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
    deliverResolutionResult();
    Helper helper = helperCaptor.getValue();
    Subchannel subchannel = createSubchannelSafely(helper, servers.get(0), Attributes.EMPTY);
    requestConnectionSafely(helper, subchannel);
    MockClientTransportInfo t0 = newTransports.poll();
    t0.listener.transportReady();
    updateSubchannelAddressesSafely(helper, subchannel, servers.get(1));
    requestConnectionSafely(helper, subchannel);
    MockClientTransportInfo t1 = newTransports.poll();
    t1.listener.transportReady();
    // Drain InternalSubchannel's delayed shutdown on updateAddresses
    timer.forwardTime(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS, TimeUnit.SECONDS);
}
Also used : Helper(io.grpc.LoadBalancer.Helper) Subchannel(io.grpc.LoadBalancer.Subchannel) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) Test(org.junit.Test)

Example 73 with Subchannel

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

the class ManagedChannelImplTest method subchannels.

@Test
public void subchannels() {
    createChannel();
    // createSubchannel() always return a new Subchannel
    Attributes attrs1 = Attributes.newBuilder().set(SUBCHANNEL_ATTR_KEY, "attr1").build();
    Attributes attrs2 = Attributes.newBuilder().set(SUBCHANNEL_ATTR_KEY, "attr2").build();
    SubchannelStateListener listener1 = mock(SubchannelStateListener.class);
    SubchannelStateListener listener2 = mock(SubchannelStateListener.class);
    final Subchannel sub1 = createSubchannelSafely(helper, addressGroup, attrs1, listener1);
    final Subchannel sub2 = createSubchannelSafely(helper, addressGroup, attrs2, listener2);
    assertNotSame(sub1, sub2);
    assertNotSame(attrs1, attrs2);
    assertSame(attrs1, sub1.getAttributes());
    assertSame(attrs2, sub2.getAttributes());
    final AtomicBoolean snippetPassed = new AtomicBoolean(false);
    helper.getSynchronizationContext().execute(new Runnable() {

        @Override
        public void run() {
            // getAddresses() must be called from sync context
            assertSame(addressGroup, sub1.getAddresses());
            assertSame(addressGroup, sub2.getAddresses());
            snippetPassed.set(true);
        }
    });
    assertThat(snippetPassed.get()).isTrue();
    // requestConnection()
    verify(mockTransportFactory, never()).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(TransportLogger.class));
    requestConnectionSafely(helper, sub1);
    verify(mockTransportFactory).newClientTransport(eq(socketAddress), eq(clientTransportOptions), isA(TransportLogger.class));
    MockClientTransportInfo transportInfo1 = transports.poll();
    assertNotNull(transportInfo1);
    requestConnectionSafely(helper, sub2);
    verify(mockTransportFactory, times(2)).newClientTransport(eq(socketAddress), eq(clientTransportOptions), isA(TransportLogger.class));
    MockClientTransportInfo transportInfo2 = transports.poll();
    assertNotNull(transportInfo2);
    requestConnectionSafely(helper, sub1);
    requestConnectionSafely(helper, sub2);
    // The subchannel doesn't matter since this isn't called
    verify(mockTransportFactory, times(2)).newClientTransport(eq(socketAddress), eq(clientTransportOptions), isA(TransportLogger.class));
    // updateAddresses()
    updateAddressesSafely(helper, sub1, Collections.singletonList(addressGroup2));
    assertThat(((InternalSubchannel) sub1.getInternalSubchannel()).getAddressGroups()).isEqualTo(Collections.singletonList(addressGroup2));
    // shutdown() has a delay
    shutdownSafely(helper, sub1);
    timer.forwardTime(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS - 1, TimeUnit.SECONDS);
    shutdownSafely(helper, sub1);
    verify(transportInfo1.transport, never()).shutdown(any(Status.class));
    timer.forwardTime(1, TimeUnit.SECONDS);
    verify(transportInfo1.transport).shutdown(same(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_STATUS));
    // ... but not after Channel is terminating
    verify(mockLoadBalancer, never()).shutdown();
    channel.shutdown();
    verify(mockLoadBalancer).shutdown();
    verify(transportInfo2.transport, never()).shutdown(any(Status.class));
    shutdownSafely(helper, sub2);
    verify(transportInfo2.transport).shutdown(same(ManagedChannelImpl.SHUTDOWN_STATUS));
    // Cleanup
    transportInfo1.listener.transportShutdown(Status.UNAVAILABLE);
    transportInfo1.listener.transportTerminated();
    transportInfo2.listener.transportShutdown(Status.UNAVAILABLE);
    transportInfo2.listener.transportTerminated();
    timer.forwardTime(ManagedChannelImpl.SUBCHANNEL_SHUTDOWN_DELAY_SECONDS, TimeUnit.SECONDS);
}
Also used : Status(io.grpc.Status) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) TransportLogger(io.grpc.internal.InternalSubchannel.TransportLogger) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Example 74 with Subchannel

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

the class ManagedChannelImplTest method hedgingScheduledThenChannelShutdown_hedgeShouldStillHappen_newCallShouldFail.

@Test
public void hedgingScheduledThenChannelShutdown_hedgeShouldStillHappen_newCallShouldFail() {
    Map<String, Object> hedgingPolicy = new HashMap<>();
    hedgingPolicy.put("maxAttempts", 3D);
    hedgingPolicy.put("hedgingDelay", "10s");
    hedgingPolicy.put("nonFatalStatusCodes", Arrays.<Object>asList("UNAVAILABLE"));
    Map<String, Object> methodConfig = new HashMap<>();
    Map<String, Object> name = new HashMap<>();
    name.put("service", "service");
    methodConfig.put("name", Arrays.<Object>asList(name));
    methodConfig.put("hedgingPolicy", hedgingPolicy);
    Map<String, Object> rawServiceConfig = new HashMap<>();
    rawServiceConfig.put("methodConfig", Arrays.<Object>asList(methodConfig));
    FakeNameResolverFactory nameResolverFactory = new FakeNameResolverFactory.Builder(expectedUri).setServers(Collections.singletonList(new EquivalentAddressGroup(socketAddress))).build();
    ManagedChannelServiceConfig managedChannelServiceConfig = createManagedChannelServiceConfig(rawServiceConfig, null);
    nameResolverFactory.nextConfigOrError.set(ConfigOrError.fromConfig(managedChannelServiceConfig));
    channelBuilder.nameResolverFactory(nameResolverFactory);
    channelBuilder.executor(MoreExecutors.directExecutor());
    channelBuilder.enableRetry();
    requestConnection = false;
    createChannel();
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, new Metadata());
    ArgumentCaptor<Helper> helperCaptor = ArgumentCaptor.forClass(Helper.class);
    verify(mockLoadBalancerProvider).newLoadBalancer(helperCaptor.capture());
    helper = helperCaptor.getValue();
    verify(mockLoadBalancer).handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(nameResolverFactory.servers).build());
    // simulating request connection and then transport ready after resolved address
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    when(mockPicker.pickSubchannel(any(PickSubchannelArgs.class))).thenReturn(PickResult.withSubchannel(subchannel));
    requestConnectionSafely(helper, subchannel);
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ClientStream mockStream = mock(ClientStream.class);
    ClientStream mockStream2 = mock(ClientStream.class);
    when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class), ArgumentMatchers.<ClientStreamTracer[]>any())).thenReturn(mockStream).thenReturn(mockStream2);
    transportInfo.listener.transportReady();
    updateBalancingStateSafely(helper, READY, mockPicker);
    ArgumentCaptor<ClientStreamListener> streamListenerCaptor = ArgumentCaptor.forClass(ClientStreamListener.class);
    verify(mockStream).start(streamListenerCaptor.capture());
    // in hedging delay backoff
    timer.forwardTime(5, TimeUnit.SECONDS);
    assertThat(timer.numPendingTasks()).isEqualTo(1);
    // first hedge fails
    streamListenerCaptor.getValue().closed(Status.UNAVAILABLE, PROCESSED, new Metadata());
    verify(mockStream2, never()).start(any(ClientStreamListener.class));
    // shutdown during backoff period
    channel.shutdown();
    assertThat(timer.numPendingTasks()).isEqualTo(1);
    verify(mockCallListener, never()).onClose(any(Status.class), any(Metadata.class));
    ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT);
    call2.start(mockCallListener2, new Metadata());
    ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
    verify(mockCallListener2).onClose(statusCaptor.capture(), any(Metadata.class));
    assertSame(Status.Code.UNAVAILABLE, statusCaptor.getValue().getCode());
    assertEquals("Channel shutdown invoked", statusCaptor.getValue().getDescription());
    // backoff ends
    timer.forwardTime(5, TimeUnit.SECONDS);
    assertThat(timer.numPendingTasks()).isEqualTo(1);
    verify(mockStream2).start(streamListenerCaptor.capture());
    verify(mockLoadBalancer, never()).shutdown();
    assertFalse("channel.isTerminated() is expected to be false but was true", channel.isTerminated());
    streamListenerCaptor.getValue().closed(Status.INTERNAL, PROCESSED, new Metadata());
    assertThat(timer.numPendingTasks()).isEqualTo(0);
    verify(mockLoadBalancer).shutdown();
    // simulating the shutdown of load balancer triggers the shutdown of subchannel
    shutdownSafely(helper, subchannel);
    // simulating transport shutdown & terminated
    transportInfo.listener.transportShutdown(Status.INTERNAL);
    transportInfo.listener.transportTerminated();
    assertTrue("channel.isTerminated() is expected to be true but was false", channel.isTerminated());
}
Also used : Status(io.grpc.Status) HashMap(java.util.HashMap) UnsupportedClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder) ClientTransportFactoryBuilder(io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) Helper(io.grpc.LoadBalancer.Helper) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 75 with Subchannel

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

the class ManagedChannelImplTest method subchannelChannel_normalUsage.

@Test
public void subchannelChannel_normalUsage() {
    createChannel();
    Subchannel subchannel = createSubchannelSafely(helper, addressGroup, Attributes.EMPTY, subchannelStateListener);
    verify(balancerRpcExecutorPool, never()).getObject();
    Channel sChannel = subchannel.asChannel();
    verify(balancerRpcExecutorPool).getObject();
    Metadata headers = new Metadata();
    CallOptions callOptions = CallOptions.DEFAULT.withDeadlineAfter(5, TimeUnit.SECONDS);
    // Subchannel must be READY when creating the RPC.
    requestConnectionSafely(helper, subchannel);
    verify(mockTransportFactory).newClientTransport(any(SocketAddress.class), any(ClientTransportOptions.class), any(ChannelLogger.class));
    MockClientTransportInfo transportInfo = transports.poll();
    ConnectionClientTransport mockTransport = transportInfo.transport;
    ManagedClientTransport.Listener transportListener = transportInfo.listener;
    transportListener.transportReady();
    ClientCall<String, Integer> call = sChannel.newCall(method, callOptions);
    call.start(mockCallListener, headers);
    verify(mockTransport).newStream(same(method), same(headers), callOptionsCaptor.capture(), ArgumentMatchers.<ClientStreamTracer[]>any());
    CallOptions capturedCallOption = callOptionsCaptor.getValue();
    assertThat(capturedCallOption.getDeadline()).isSameInstanceAs(callOptions.getDeadline());
    assertThat(capturedCallOption.getOption(GrpcUtil.CALL_OPTIONS_RPC_OWNED_BY_BALANCER)).isTrue();
}
Also used : ClientStreamTracer(io.grpc.ClientStreamTracer) ClientTransportOptions(io.grpc.internal.ClientTransportFactory.ClientTransportOptions) ManagedChannel(io.grpc.ManagedChannel) Channel(io.grpc.Channel) Metadata(io.grpc.Metadata) MockClientTransportInfo(io.grpc.internal.TestUtils.MockClientTransportInfo) CallOptions(io.grpc.CallOptions) ForwardingSubchannel(io.grpc.util.ForwardingSubchannel) Subchannel(io.grpc.LoadBalancer.Subchannel) ChannelLogger(io.grpc.ChannelLogger) ProxiedSocketAddress(io.grpc.ProxiedSocketAddress) SocketAddress(java.net.SocketAddress) Test(org.junit.Test)

Aggregations

Subchannel (io.grpc.LoadBalancer.Subchannel)125 Test (org.junit.Test)108 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)54 InOrder (org.mockito.InOrder)43 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)42 Metadata (io.grpc.Metadata)40 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)35 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)33 ForwardingSubchannel (io.grpc.util.ForwardingSubchannel)32 MockClientTransportInfo (io.grpc.internal.TestUtils.MockClientTransportInfo)30 Attributes (io.grpc.Attributes)26 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)25 ClientStreamTracer (io.grpc.ClientStreamTracer)24 Status (io.grpc.Status)23 PickResult (io.grpc.LoadBalancer.PickResult)19 CallOptions (io.grpc.CallOptions)18 ConnectivityState (io.grpc.ConnectivityState)18 Helper (io.grpc.LoadBalancer.Helper)18 SocketAddress (java.net.SocketAddress)18 ChannelLogger (io.grpc.ChannelLogger)14