Search in sources :

Example 96 with Subchannel

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

the class GrpclbLoadBalancerTest method subtestGrpclbFallbackInitialTimeout.

// Fallback or not within the period of the initial timeout.
private void subtestGrpclbFallbackInitialTimeout(boolean timerExpires) {
    long loadReportIntervalMillis = 1983;
    InOrder inOrder = inOrder(helper, subchannelPool);
    // Create balancer and backend addresses
    List<EquivalentAddressGroup> backendList = createResolvedBackendAddresses(2);
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    inOrder.verify(helper).createOobChannel(eq(xattr(grpclbBalancerList)), eq(lbAuthority(0) + NO_USE_AUTHORITY_SUFFIX));
    // Attempted to connect to balancer
    assertEquals(1, fakeOobChannels.size());
    ManagedChannel oobChannel = fakeOobChannels.poll();
    verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
    verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // We don't care if these methods have been run.
    inOrder.verify(helper, atLeast(0)).getSynchronizationContext();
    inOrder.verify(helper, atLeast(0)).getScheduledExecutorService();
    inOrder.verifyNoMoreInteractions();
    assertEquals(1, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    fakeClock.forwardTime(GrpclbState.FALLBACK_TIMEOUT_MS - 1, TimeUnit.MILLISECONDS);
    assertEquals(1, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    // ////////////////////////////////
    if (timerExpires) {
        logs.clear();
        fakeClock.forwardTime(1, TimeUnit.MILLISECONDS);
        assertEquals(0, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
        assertThat(logs).containsExactly("INFO: [grpclb-<api.google.com>] Using fallback backends").inOrder();
        // Fall back to the backends from resolver
        fallbackTestVerifyUseOfFallbackBackendLists(inOrder, backendList);
        assertFalse(oobChannel.isShutdown());
        verify(lbRequestObserver, never()).onCompleted();
    }
    // ////////////////////////////////////////////////////////////////////
    // Name resolver sends new resolution results without any backend addr
    // ////////////////////////////////////////////////////////////////////
    grpclbBalancerList = createResolvedBalancerAddresses(2);
    deliverResolvedAddresses(Collections.<EquivalentAddressGroup>emptyList(), grpclbBalancerList);
    // New addresses are updated to the OobChannel
    inOrder.verify(helper).updateOobChannelAddresses(same(oobChannel), eq(xattr(grpclbBalancerList)));
    if (timerExpires) {
        // Still in fallback logic, except that the backend list is empty
        for (Subchannel subchannel : mockSubchannels) {
            verify(subchannelPool).returnSubchannel(eq(subchannel), any(ConnectivityStateInfo.class));
        }
        // RPC error status includes message of balancer RPC timeout
        inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
        PickResult result = pickerCaptor.getValue().pickSubchannel(mock(PickSubchannelArgs.class));
        assertThat(result.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
        assertThat(result.getStatus().getDescription()).startsWith(GrpclbState.NO_FALLBACK_BACKENDS_STATUS.getDescription());
        assertThat(result.getStatus().getDescription()).contains(GrpclbState.BALANCER_TIMEOUT_STATUS.getDescription());
    }
    // //////////////////////////////////////////////////////////////
    // Name resolver sends new resolution results with backend addrs
    // //////////////////////////////////////////////////////////////
    // prevents the cached subchannel to be used
    subchannelPool.clear();
    backendList = createResolvedBackendAddresses(2);
    grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    // New LB address is updated to the OobChannel
    inOrder.verify(helper).updateOobChannelAddresses(same(oobChannel), eq(xattr(grpclbBalancerList)));
    if (timerExpires) {
        // New backend addresses are used for fallback
        fallbackTestVerifyUseOfFallbackBackendLists(inOrder, Arrays.asList(backendList.get(0), backendList.get(1)));
    }
    // //////////////////////////////////////////////
    if (timerExpires) {
        Status streamError = Status.UNAVAILABLE.withDescription("OOB stream broken");
        lbResponseObserver.onError(streamError.asException());
        // The error will NOT propagate to picker because fallback list is in use.
        inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
        // A new stream is created
        verify(mockLbService, times(2)).balanceLoad(lbResponseObserverCaptor.capture());
        lbResponseObserver = lbResponseObserverCaptor.getValue();
        assertEquals(1, lbRequestObservers.size());
        lbRequestObserver = lbRequestObservers.poll();
        verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    }
    // ///////////////////////////////
    // Balancer returns a server list
    // ///////////////////////////////
    List<ServerEntry> serverList = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
    lbResponseObserver.onNext(buildInitialResponse());
    lbResponseObserver.onNext(buildLbResponse(serverList));
    // Balancer-provided server list now in effect
    fallbackTestVerifyUseOfBalancerBackendLists(inOrder, serverList);
    // /////////////////////////////////////////////////////////////
    // New backend addresses from resolver outside of fallback mode
    // /////////////////////////////////////////////////////////////
    backendList = createResolvedBackendAddresses(1);
    grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList);
    // Will not affect the round robin list at all
    inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    // No fallback timeout timer scheduled.
    assertEquals(0, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) ConnectivityState(io.grpc.ConnectivityState) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest) PickResult(io.grpc.LoadBalancer.PickResult) ManagedChannel(io.grpc.ManagedChannel) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs)

Example 97 with Subchannel

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

the class GrpclbLoadBalancerTest method fallbackTestVerifyUseOfBackendLists.

private List<Subchannel> fallbackTestVerifyUseOfBackendLists(InOrder inOrder, List<EquivalentAddressGroup> addrs, @Nullable List<String> tokens) {
    if (tokens != null) {
        assertEquals(addrs.size(), tokens.size());
    }
    for (EquivalentAddressGroup addr : addrs) {
        inOrder.verify(subchannelPool).takeOrCreateSubchannel(eq(addr), any(Attributes.class));
    }
    RoundRobinPicker picker = (RoundRobinPicker) currentPicker;
    assertThat(picker.dropList).containsExactlyElementsIn(Collections.nCopies(addrs.size(), null));
    assertThat(picker.pickList).containsExactly(GrpclbState.BUFFER_ENTRY);
    assertEquals(addrs.size(), mockSubchannels.size());
    ArrayList<Subchannel> subchannels = new ArrayList<>(mockSubchannels);
    mockSubchannels.clear();
    for (Subchannel subchannel : subchannels) {
        deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(CONNECTING));
    }
    inOrder.verify(helper, atLeast(0)).updateBalancingState(eq(CONNECTING), any(SubchannelPicker.class));
    inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    ArrayList<BackendEntry> pickList = new ArrayList<>();
    for (int i = 0; i < addrs.size(); i++) {
        Subchannel subchannel = subchannels.get(i);
        BackendEntry backend;
        if (tokens == null) {
            backend = new BackendEntry(subchannel);
        } else {
            backend = new BackendEntry(subchannel, getLoadRecorder(), tokens.get(i));
        }
        pickList.add(backend);
        deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
        inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
        picker = (RoundRobinPicker) pickerCaptor.getValue();
        assertThat(picker.dropList).containsExactlyElementsIn(Collections.nCopies(addrs.size(), null));
        assertThat(picker.pickList).containsExactlyElementsIn(pickList);
        inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    }
    return subchannels;
}
Also used : BackendEntry(io.grpc.grpclb.GrpclbState.BackendEntry) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) RoundRobinPicker(io.grpc.grpclb.GrpclbState.RoundRobinPicker) ConnectivityState(io.grpc.ConnectivityState) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) Attributes(io.grpc.Attributes) ArrayList(java.util.ArrayList)

Example 98 with Subchannel

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

the class GrpclbLoadBalancerTest method roundRobinPickerWithDrop.

@Test
public void roundRobinPickerWithDrop() {
    assertTrue(DROP_PICK_RESULT.isDrop());
    GrpclbClientLoadRecorder loadRecorder = new GrpclbClientLoadRecorder(fakeClock.getTimeProvider());
    Subchannel subchannel = mock(Subchannel.class);
    // 1 out of 2 requests are to be dropped
    DropEntry d = new DropEntry(loadRecorder, "LBTOKEN0003");
    List<DropEntry> dropList = Arrays.asList(null, d);
    BackendEntry b1 = new BackendEntry(subchannel, loadRecorder, "LBTOKEN0001");
    BackendEntry b2 = new BackendEntry(subchannel, loadRecorder, "LBTOKEN0002");
    List<BackendEntry> pickList = Arrays.asList(b1, b2);
    RoundRobinPicker picker = new RoundRobinPicker(dropList, pickList);
    // dropList[0], pickList[0]
    PickSubchannelArgs args1 = mock(PickSubchannelArgs.class);
    Metadata headers1 = new Metadata();
    headers1.put(GrpclbConstants.TOKEN_METADATA_KEY, "LBTOKEN__OLD");
    when(args1.getHeaders()).thenReturn(headers1);
    assertSame(b1.result, picker.pickSubchannel(args1));
    verify(args1).getHeaders();
    assertThat(headers1.getAll(GrpclbConstants.TOKEN_METADATA_KEY)).containsExactly("LBTOKEN0001");
    // dropList[1]: drop
    PickSubchannelArgs args2 = mock(PickSubchannelArgs.class);
    Metadata headers2 = new Metadata();
    when(args2.getHeaders()).thenReturn(headers2);
    assertSame(DROP_PICK_RESULT, picker.pickSubchannel(args2));
    verify(args2, never()).getHeaders();
    // dropList[0], pickList[1]
    PickSubchannelArgs args3 = mock(PickSubchannelArgs.class);
    Metadata headers3 = new Metadata();
    when(args3.getHeaders()).thenReturn(headers3);
    assertSame(b2.result, picker.pickSubchannel(args3));
    verify(args3).getHeaders();
    assertThat(headers3.getAll(GrpclbConstants.TOKEN_METADATA_KEY)).containsExactly("LBTOKEN0002");
    // dropList[1]: drop
    PickSubchannelArgs args4 = mock(PickSubchannelArgs.class);
    Metadata headers4 = new Metadata();
    when(args4.getHeaders()).thenReturn(headers4);
    assertSame(DROP_PICK_RESULT, picker.pickSubchannel(args4));
    verify(args4, never()).getHeaders();
    // dropList[0], pickList[0]
    PickSubchannelArgs args5 = mock(PickSubchannelArgs.class);
    Metadata headers5 = new Metadata();
    when(args5.getHeaders()).thenReturn(headers5);
    assertSame(b1.result, picker.pickSubchannel(args5));
    verify(args5).getHeaders();
    assertThat(headers5.getAll(GrpclbConstants.TOKEN_METADATA_KEY)).containsExactly("LBTOKEN0001");
    verify(subchannel, never()).getAttributes();
}
Also used : BackendEntry(io.grpc.grpclb.GrpclbState.BackendEntry) RoundRobinPicker(io.grpc.grpclb.GrpclbState.RoundRobinPicker) DropEntry(io.grpc.grpclb.GrpclbState.DropEntry) Subchannel(io.grpc.LoadBalancer.Subchannel) Metadata(io.grpc.Metadata) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 99 with Subchannel

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

the class GrpclbLoadBalancerTest method tearDown.

@After
public void tearDown() {
    try {
        if (balancer != null) {
            syncContext.execute(new Runnable() {

                @Override
                public void run() {
                    balancer.shutdown();
                }
            });
        }
        for (ManagedChannel channel : oobChannelTracker) {
            assertTrue(channel + " is shutdown", channel.isShutdown());
            // balancer should have closed the LB stream, terminating the OOB channel.
            assertTrue(channel + " is terminated", channel.isTerminated());
        }
        for (Subchannel subchannel : unpooledSubchannelTracker) {
            verify(subchannel).shutdown();
        }
        // No timer should linger after shutdown
        assertThat(fakeClock.getPendingTasks()).isEmpty();
    } finally {
        if (fakeLbServer != null) {
            fakeLbServer.shutdownNow();
        }
    }
}
Also used : Subchannel(io.grpc.LoadBalancer.Subchannel) ManagedChannel(io.grpc.ManagedChannel) After(org.junit.After)

Example 100 with Subchannel

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

the class GrpclbState method shutdown.

void shutdown() {
    logger.log(ChannelLogLevel.INFO, "[grpclb-<{0}>] Shutdown", serviceName);
    shutdownLbComm();
    switch(config.getMode()) {
        case ROUND_ROBIN:
            // testing.
            for (Subchannel subchannel : subchannels.values()) {
                returnSubchannelToPool(subchannel);
            }
            subchannelPool.clear();
            break;
        case PICK_FIRST:
            if (!subchannels.isEmpty()) {
                checkState(subchannels.size() == 1, "Excessive Subchannels: %s", subchannels);
                subchannels.values().iterator().next().shutdown();
            }
            break;
        default:
            throw new AssertionError("Missing case for " + config.getMode());
    }
    subchannels = Collections.emptyMap();
    cancelFallbackTimer();
    cancelLbRpcRetryTimer();
}
Also used : Subchannel(io.grpc.LoadBalancer.Subchannel)

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