Search in sources :

Example 1 with ConnectivityState

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

the class PickFirstLoadBalancer method processSubchannelState.

private void processSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
    ConnectivityState currentState = stateInfo.getState();
    if (currentState == SHUTDOWN) {
        return;
    }
    if (stateInfo.getState() == TRANSIENT_FAILURE || stateInfo.getState() == IDLE) {
        helper.refreshNameResolution();
    }
    SubchannelPicker picker;
    switch(currentState) {
        case IDLE:
            picker = new RequestConnectionPicker(subchannel);
            break;
        case CONNECTING:
            // It's safe to use RequestConnectionPicker here, so when coming from IDLE we could leave
            // the current picker in-place. But ignoring the potential optimization is simpler.
            picker = new Picker(PickResult.withNoResult());
            break;
        case READY:
            picker = new Picker(PickResult.withSubchannel(subchannel));
            break;
        case TRANSIENT_FAILURE:
            picker = new Picker(PickResult.withError(stateInfo.getStatus()));
            break;
        default:
            throw new IllegalArgumentException("Unsupported state:" + currentState);
    }
    helper.updateBalancingState(currentState, picker);
}
Also used : ConnectivityState(io.grpc.ConnectivityState)

Example 2 with ConnectivityState

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

the class RoundRobinLoadBalancerTest method subchannelStateIsolation.

@Test
public void subchannelStateIsolation() throws Exception {
    Iterator<Subchannel> subchannelIterator = subchannels.values().iterator();
    Subchannel sc1 = subchannelIterator.next();
    Subchannel sc2 = subchannelIterator.next();
    Subchannel sc3 = subchannelIterator.next();
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY).build());
    verify(sc1, times(1)).requestConnection();
    verify(sc2, times(1)).requestConnection();
    verify(sc3, times(1)).requestConnection();
    deliverSubchannelState(sc1, ConnectivityStateInfo.forNonError(READY));
    deliverSubchannelState(sc2, ConnectivityStateInfo.forNonError(READY));
    deliverSubchannelState(sc3, ConnectivityStateInfo.forNonError(READY));
    deliverSubchannelState(sc2, ConnectivityStateInfo.forNonError(IDLE));
    deliverSubchannelState(sc3, ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE));
    verify(mockHelper, times(6)).updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
    Iterator<ConnectivityState> stateIterator = stateCaptor.getAllValues().iterator();
    Iterator<SubchannelPicker> pickers = pickerCaptor.getAllValues().iterator();
    // The picker is incrementally updated as subchannels become READY
    assertEquals(CONNECTING, stateIterator.next());
    assertThat(pickers.next()).isInstanceOf(EmptyPicker.class);
    assertEquals(READY, stateIterator.next());
    assertThat(getList(pickers.next())).containsExactly(sc1);
    assertEquals(READY, stateIterator.next());
    assertThat(getList(pickers.next())).containsExactly(sc1, sc2);
    assertEquals(READY, stateIterator.next());
    assertThat(getList(pickers.next())).containsExactly(sc1, sc2, sc3);
    // The IDLE subchannel is dropped from the picker, but a reconnection is requested
    assertEquals(READY, stateIterator.next());
    assertThat(getList(pickers.next())).containsExactly(sc1, sc3);
    verify(sc2, times(2)).requestConnection();
    // The failing subchannel is dropped from the picker, with no requested reconnect
    assertEquals(READY, stateIterator.next());
    assertThat(getList(pickers.next())).containsExactly(sc1);
    verify(sc3, times(1)).requestConnection();
    assertThat(stateIterator.hasNext()).isFalse();
    assertThat(pickers.hasNext()).isFalse();
}
Also used : SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) ConnectivityState(io.grpc.ConnectivityState) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 3 with ConnectivityState

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

the class RoundRobinLoadBalancerTest method nameResolutionErrorWithActiveChannels.

@Test
public void nameResolutionErrorWithActiveChannels() throws Exception {
    final Subchannel readySubchannel = subchannels.values().iterator().next();
    loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity).build());
    deliverSubchannelState(readySubchannel, ConnectivityStateInfo.forNonError(READY));
    loadBalancer.handleNameResolutionError(Status.NOT_FOUND.withDescription("nameResolutionError"));
    verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
    verify(mockHelper, times(2)).updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
    Iterator<ConnectivityState> stateIterator = stateCaptor.getAllValues().iterator();
    assertEquals(CONNECTING, stateIterator.next());
    assertEquals(READY, stateIterator.next());
    LoadBalancer.PickResult pickResult = pickerCaptor.getValue().pickSubchannel(mockArgs);
    assertEquals(readySubchannel, pickResult.getSubchannel());
    assertEquals(Status.OK.getCode(), pickResult.getStatus().getCode());
    LoadBalancer.PickResult pickResult2 = pickerCaptor.getValue().pickSubchannel(mockArgs);
    assertEquals(readySubchannel, pickResult2.getSubchannel());
    verifyNoMoreInteractions(mockHelper);
}
Also used : ConnectivityState(io.grpc.ConnectivityState) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalancer(io.grpc.LoadBalancer) PickResult(io.grpc.LoadBalancer.PickResult) Test(org.junit.Test)

Example 4 with ConnectivityState

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

the class SubchannelStateManagerImpl method updateState.

@Override
public void updateState(String name, ConnectivityState newState) {
    checkNotNull(name, "name");
    checkNotNull(newState, "newState");
    ConnectivityState existing;
    if (newState == ConnectivityState.SHUTDOWN) {
        existing = stateMap.remove(name);
    } else {
        existing = stateMap.put(name, newState);
        stateMultiset.add(newState);
    }
    if (existing != null) {
        stateMultiset.remove(existing);
    }
}
Also used : ConnectivityState(io.grpc.ConnectivityState)

Example 5 with ConnectivityState

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

the class RingHashLoadBalancer method updateBalancingState.

/**
 * Updates the overall balancing state by aggregating the connectivity states of all subchannels.
 *
 * <p>Aggregation rules (in order of dominance):
 * <ol>
 *   <li>If there is at least one subchannel in READY state, overall state is READY</li>
 *   <li>If there are <em>2 or more</em> subchannels in TRANSIENT_FAILURE, overall state is
 *   TRANSIENT_FAILURE</li>
 *   <li>If there is at least one subchannel in CONNECTING state, overall state is
 *   CONNECTING</li>
 *   <li>If there is at least one subchannel in IDLE state, overall state is IDLE</li>
 *   <li>Otherwise, overall state is TRANSIENT_FAILURE</li>
 * </ol>
 */
private void updateBalancingState() {
    checkState(!subchannels.isEmpty(), "no subchannel has been created");
    int failureCount = 0;
    boolean hasConnecting = false;
    Subchannel idleSubchannel = null;
    ConnectivityState overallState = null;
    for (Subchannel subchannel : subchannels.values()) {
        ConnectivityState state = getSubchannelStateInfoRef(subchannel).value.getState();
        if (state == READY) {
            overallState = READY;
            break;
        }
        if (state == TRANSIENT_FAILURE) {
            failureCount++;
        } else if (state == CONNECTING) {
            hasConnecting = true;
        } else if (state == IDLE) {
            if (idleSubchannel == null) {
                idleSubchannel = subchannel;
            }
        }
    }
    if (overallState == null) {
        if (failureCount >= 2) {
            // one subchannel that has not failed at any given time.
            if (!hasConnecting && idleSubchannel != null) {
                idleSubchannel.requestConnection();
            }
            overallState = TRANSIENT_FAILURE;
        } else if (hasConnecting) {
            overallState = CONNECTING;
        } else if (idleSubchannel != null) {
            overallState = IDLE;
        } else {
            overallState = TRANSIENT_FAILURE;
        }
    }
    RingHashPicker picker = new RingHashPicker(syncContext, ring, subchannels);
    // TODO(chengyuanzhang): avoid unnecessary reprocess caused by duplicated server addr updates
    helper.updateBalancingState(overallState, picker);
    currentState = overallState;
}
Also used : ConnectivityState(io.grpc.ConnectivityState)

Aggregations

ConnectivityState (io.grpc.ConnectivityState)12 Test (org.junit.Test)6 Subchannel (io.grpc.LoadBalancer.Subchannel)5 PickResult (io.grpc.LoadBalancer.PickResult)3 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)3 LoadBalancer (io.grpc.LoadBalancer)2 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)2 Attributes (io.grpc.Attributes)1 ConnectivityStateInfo (io.grpc.ConnectivityStateInfo)1 Metadata (io.grpc.Metadata)1 Status (io.grpc.Status)1 PickSubchannelArgsImpl (io.grpc.internal.PickSubchannelArgsImpl)1 CachedRouteLookupResponse (io.grpc.rls.CachingRlsLbClient.CachedRouteLookupResponse)1 RouteLookupRequest (io.grpc.rls.RlsProtoData.RouteLookupRequest)1 LeastRequestConfig (io.grpc.xds.LeastRequestLoadBalancer.LeastRequestConfig)1 WeightedChildPicker (io.grpc.xds.WeightedRandomPicker.WeightedChildPicker)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 InOrder (org.mockito.InOrder)1