Search in sources :

Example 1 with ConnectivityStateInfo

use of io.grpc.ConnectivityStateInfo in project grpc-java by grpc.

the class RoundRobinLoadBalancer method updateBalancingState.

/**
 * Updates picker with the list of active subchannels (state == READY).
 */
@SuppressWarnings("ReferenceEquality")
private void updateBalancingState() {
    List<Subchannel> activeList = filterNonFailingSubchannels(getSubchannels());
    if (activeList.isEmpty()) {
        // No READY subchannels, determine aggregate state and error status
        boolean isConnecting = false;
        Status aggStatus = EMPTY_OK;
        for (Subchannel subchannel : getSubchannels()) {
            ConnectivityStateInfo stateInfo = getSubchannelStateInfoRef(subchannel).value;
            // RRLB will request connection immediately on subchannel IDLE.
            if (stateInfo.getState() == CONNECTING || stateInfo.getState() == IDLE) {
                isConnecting = true;
            }
            if (aggStatus == EMPTY_OK || !aggStatus.isOk()) {
                aggStatus = stateInfo.getStatus();
            }
        }
        updateBalancingState(isConnecting ? CONNECTING : TRANSIENT_FAILURE, // an arbitrary subchannel, otherwise return OK.
        new EmptyPicker(aggStatus));
    } else {
        // initialize the Picker to a random start index to ensure that a high frequency of Picker
        // churn does not skew subchannel selection.
        int startIndex = random.nextInt(activeList.size());
        updateBalancingState(READY, new ReadyPicker(activeList, startIndex));
    }
}
Also used : Status(io.grpc.Status) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo)

Example 2 with ConnectivityStateInfo

use of io.grpc.ConnectivityStateInfo in project grpc-java by grpc.

the class RoundRobinLoadBalancer method handleResolvedAddresses.

@Override
public void handleResolvedAddresses(ResolvedAddresses resolvedAddresses) {
    List<EquivalentAddressGroup> servers = resolvedAddresses.getAddresses();
    Set<EquivalentAddressGroup> currentAddrs = subchannels.keySet();
    Map<EquivalentAddressGroup, EquivalentAddressGroup> latestAddrs = stripAttrs(servers);
    Set<EquivalentAddressGroup> removedAddrs = setsDifference(currentAddrs, latestAddrs.keySet());
    for (Map.Entry<EquivalentAddressGroup, EquivalentAddressGroup> latestEntry : latestAddrs.entrySet()) {
        EquivalentAddressGroup strippedAddressGroup = latestEntry.getKey();
        EquivalentAddressGroup originalAddressGroup = latestEntry.getValue();
        Subchannel existingSubchannel = subchannels.get(strippedAddressGroup);
        if (existingSubchannel != null) {
            // EAG's Attributes may have changed.
            existingSubchannel.updateAddresses(Collections.singletonList(originalAddressGroup));
            continue;
        }
        // Create new subchannels for new addresses.
        // NB(lukaszx0): we don't merge `attributes` with `subchannelAttr` because subchannel
        // doesn't need them. They're describing the resolved server list but we're not taking
        // any action based on this information.
        Attributes.Builder subchannelAttrs = Attributes.newBuilder().set(STATE_INFO, new Ref<>(ConnectivityStateInfo.forNonError(IDLE)));
        final Subchannel subchannel = checkNotNull(helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(originalAddressGroup).setAttributes(subchannelAttrs.build()).build()), "subchannel");
        subchannel.start(new SubchannelStateListener() {

            @Override
            public void onSubchannelState(ConnectivityStateInfo state) {
                processSubchannelState(subchannel, state);
            }
        });
        subchannels.put(strippedAddressGroup, subchannel);
        subchannel.requestConnection();
    }
    ArrayList<Subchannel> removedSubchannels = new ArrayList<>();
    for (EquivalentAddressGroup addressGroup : removedAddrs) {
        removedSubchannels.add(subchannels.remove(addressGroup));
    }
    // Update the picker before shutting down the subchannels, to reduce the chance of the race
    // between picking a subchannel and shutting it down.
    updateBalancingState();
    // Shutdown removed subchannels
    for (Subchannel removedSubchannel : removedSubchannels) {
        shutdownSubchannel(removedSubchannel);
    }
}
Also used : Attributes(io.grpc.Attributes) ArrayList(java.util.ArrayList) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with ConnectivityStateInfo

use of io.grpc.ConnectivityStateInfo in project grpc-java by grpc.

the class AutoConfiguredLoadBalancerFactoryTest method forwardsCalls.

@SuppressWarnings("deprecation")
@Test
public void forwardsCalls() {
    AutoConfiguredLoadBalancer lb = lbf.newLoadBalancer(new TestHelper());
    final AtomicInteger calls = new AtomicInteger();
    TestLoadBalancer testlb = new TestLoadBalancer() {

        @Override
        public void handleNameResolutionError(Status error) {
            calls.getAndSet(1);
        }

        @Override
        public void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
            calls.getAndSet(2);
        }

        @Override
        public void shutdown() {
            calls.getAndSet(3);
        }
    };
    lb.setDelegate(testlb);
    lb.handleNameResolutionError(Status.RESOURCE_EXHAUSTED);
    assertThat(calls.getAndSet(0)).isEqualTo(1);
    lb.handleSubchannelState(null, null);
    assertThat(calls.getAndSet(0)).isEqualTo(2);
    lb.shutdown();
    assertThat(calls.getAndSet(0)).isEqualTo(3);
}
Also used : AutoConfiguredLoadBalancer(io.grpc.internal.AutoConfiguredLoadBalancerFactory.AutoConfiguredLoadBalancer) Status(io.grpc.Status) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 4 with ConnectivityStateInfo

use of io.grpc.ConnectivityStateInfo in project grpc-java by grpc.

the class RoundRobinLoadBalancerTest method stayTransientFailureUntilReady.

@Test
public void stayTransientFailureUntilReady() {
    InOrder inOrder = inOrder(mockHelper);
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY).build());
    inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
    // Simulate state transitions for each subchannel individually.
    for (Subchannel sc : loadBalancer.getSubchannels()) {
        Status error = Status.UNKNOWN.withDescription("connection broken");
        deliverSubchannelState(sc, ConnectivityStateInfo.forTransientFailure(error));
        inOrder.verify(mockHelper).refreshNameResolution();
        deliverSubchannelState(sc, ConnectivityStateInfo.forNonError(CONNECTING));
        Ref<ConnectivityStateInfo> scStateInfo = sc.getAttributes().get(STATE_INFO);
        assertThat(scStateInfo.value.getState()).isEqualTo(TRANSIENT_FAILURE);
        assertThat(scStateInfo.value.getStatus()).isEqualTo(error);
    }
    inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), isA(EmptyPicker.class));
    inOrder.verifyNoMoreInteractions();
    Subchannel subchannel = loadBalancer.getSubchannels().iterator().next();
    deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
    Ref<ConnectivityStateInfo> subchannelStateInfo = subchannel.getAttributes().get(STATE_INFO);
    assertThat(subchannelStateInfo.value).isEqualTo(ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(mockHelper).updateBalancingState(eq(READY), isA(ReadyPicker.class));
    verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
    verifyNoMoreInteractions(mockHelper);
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EmptyPicker(io.grpc.util.RoundRobinLoadBalancer.EmptyPicker) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) Subchannel(io.grpc.LoadBalancer.Subchannel) ReadyPicker(io.grpc.util.RoundRobinLoadBalancer.ReadyPicker) Test(org.junit.Test)

Example 5 with ConnectivityStateInfo

use of io.grpc.ConnectivityStateInfo in project grpc-java by grpc.

the class LeastRequestLoadBalancerTest method stayTransientFailureUntilReady.

@Test
public void stayTransientFailureUntilReady() {
    InOrder inOrder = inOrder(mockHelper);
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY).build());
    inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
    // Simulate state transitions for each subchannel individually.
    for (Subchannel sc : loadBalancer.getSubchannels()) {
        Status error = Status.UNKNOWN.withDescription("connection broken");
        deliverSubchannelState(sc, ConnectivityStateInfo.forTransientFailure(error));
        inOrder.verify(mockHelper).refreshNameResolution();
        deliverSubchannelState(sc, ConnectivityStateInfo.forNonError(CONNECTING));
        Ref<ConnectivityStateInfo> scStateInfo = sc.getAttributes().get(STATE_INFO);
        assertThat(scStateInfo.value.getState()).isEqualTo(TRANSIENT_FAILURE);
        assertThat(scStateInfo.value.getStatus()).isEqualTo(error);
    }
    inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), isA(EmptyPicker.class));
    inOrder.verifyNoMoreInteractions();
    Subchannel subchannel = loadBalancer.getSubchannels().iterator().next();
    deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
    Ref<ConnectivityStateInfo> subchannelStateInfo = subchannel.getAttributes().get(STATE_INFO);
    assertThat(subchannelStateInfo.value).isEqualTo(ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(mockHelper).updateBalancingState(eq(READY), isA(ReadyPicker.class));
    verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
    verifyNoMoreInteractions(mockHelper);
}
Also used : Status(io.grpc.Status) InOrder(org.mockito.InOrder) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) EmptyPicker(io.grpc.xds.LeastRequestLoadBalancer.EmptyPicker) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) Subchannel(io.grpc.LoadBalancer.Subchannel) ReadyPicker(io.grpc.xds.LeastRequestLoadBalancer.ReadyPicker) Test(org.junit.Test)

Aggregations

ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)20 Subchannel (io.grpc.LoadBalancer.Subchannel)14 Test (org.junit.Test)10 Attributes (io.grpc.Attributes)9 Status (io.grpc.Status)9 InOrder (org.mockito.InOrder)7 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)6 ArrayList (java.util.ArrayList)5 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)4 SubchannelStateListener (io.grpc.LoadBalancer.SubchannelStateListener)4 HashMap (java.util.HashMap)4 Map (java.util.Map)3 ConnectivityState (io.grpc.ConnectivityState)2 ResolvedAddresses (io.grpc.LoadBalancer.ResolvedAddresses)2 EmptyPicker (io.grpc.util.RoundRobinLoadBalancer.EmptyPicker)2 EmptyPicker (io.grpc.xds.LeastRequestLoadBalancer.EmptyPicker)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Helper (io.grpc.LoadBalancer.Helper)1 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)1 ManagedChannel (io.grpc.ManagedChannel)1