io.grpc.ConnectivityStateInfo Java Examples

The following examples show how to use io.grpc.ConnectivityStateInfo. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LbPolicyConfiguration.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Override
public Subchannel createSubchannel(CreateSubchannelArgs args) {
  final Subchannel subchannel = super.createSubchannel(args);
  return new ForwardingSubchannel() {
    @Override
    protected Subchannel delegate() {
      return subchannel;
    }

    @Override
    public void start(final SubchannelStateListener listener) {
      super.start(new SubchannelStateListener() {
        @Override
        public void onSubchannelState(ConnectivityStateInfo newState) {
          setConnectivityStateInfo(newState);
          listener.onSubchannelState(newState);
        }
      });
    }
  };
}
 
Example #2
Source File: CachedSubchannelPool.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Override
public void returnSubchannel(Subchannel subchannel, ConnectivityStateInfo lastKnownState) {
  CacheEntry prev = cache.get(subchannel.getAddresses());
  if (prev != null) {
    // Returning the same Subchannel twice has no effect.
    // Returning a different Subchannel for an already cached EAG will cause the
    // latter Subchannel to be shutdown immediately.
    if (prev.subchannel != subchannel) {
      subchannel.shutdown();
    }
    return;
  }
  final ShutdownSubchannelTask shutdownTask = new ShutdownSubchannelTask(subchannel);
  ScheduledHandle shutdownTimer =
      helper.getSynchronizationContext().schedule(
          shutdownTask, SHUTDOWN_TIMEOUT_MS, TimeUnit.MILLISECONDS,
          helper.getScheduledExecutorService());
  CacheEntry entry = new CacheEntry(subchannel, shutdownTimer, lastKnownState);
  cache.put(subchannel.getAddresses(), entry);
}
 
Example #3
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
void handleResponse(HealthCheckResponse response) {
  callHasResponded = true;
  backoffPolicy = null;
  ServingStatus status = response.getStatus();
  // running == true means the Subchannel's state (rawState) is READY
  if (Objects.equal(status, ServingStatus.SERVING)) {
    subchannelLogger.log(ChannelLogLevel.INFO, "READY: health-check responded SERVING");
    gotoState(ConnectivityStateInfo.forNonError(READY));
  } else {
    subchannelLogger.log(
        ChannelLogLevel.INFO, "TRANSIENT_FAILURE: health-check responded {0}", status);
    gotoState(
        ConnectivityStateInfo.forTransientFailure(
            Status.UNAVAILABLE.withDescription(
                "Health-check service responded "
                + status + " for '" + callServiceName + "'")));
  }
  call.request(1);
}
 
Example #4
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
private void startRpc() {
  checkState(serviceName != null, "serviceName is null");
  checkState(activeRpc == null, "previous health-checking RPC has not been cleaned up");
  checkState(subchannel != null, "init() not called");
  // Optimization suggested by @markroth: if we are already READY and starting the health
  // checking RPC, either because health check is just enabled or has switched to a new service
  // name, we don't go to CONNECTING, otherwise there will be artificial delays on RPCs
  // waiting for the health check to respond.
  if (!Objects.equal(concludedState.getState(), READY)) {
    subchannelLogger.log(
        ChannelLogLevel.INFO, "CONNECTING: Starting health-check for \"{0}\"", serviceName);
    gotoState(ConnectivityStateInfo.forNonError(CONNECTING));
  }
  activeRpc = new HcStream();
  activeRpc.start();
}
 
Example #5
Source File: RoundRobinLoadBalancerTest.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@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(3))
      .updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());

  Iterator<ConnectivityState> stateIterator = stateCaptor.getAllValues().iterator();
  assertEquals(CONNECTING, stateIterator.next());
  assertEquals(READY, stateIterator.next());
  assertEquals(TRANSIENT_FAILURE, 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);
}
 
Example #6
Source File: PickFirstLoadBalancerTest.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Test
public void requestConnectionPicker() throws Exception {
  loadBalancer.handleResolvedAddresses(
      ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity).build());

  InOrder inOrder = inOrder(mockHelper, mockSubchannel);
  inOrder.verify(mockSubchannel).start(stateListenerCaptor.capture());
  SubchannelStateListener stateListener = stateListenerCaptor.getValue();
  inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), any(SubchannelPicker.class));
  inOrder.verify(mockSubchannel).requestConnection();

  stateListener.onSubchannelState(ConnectivityStateInfo.forNonError(IDLE));
  inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());

  SubchannelPicker picker = pickerCaptor.getValue();

  // Calling pickSubchannel() twice gave the same result
  assertEquals(picker.pickSubchannel(mockArgs), picker.pickSubchannel(mockArgs));

  // But the picker calls requestConnection() only once
  inOrder.verify(mockSubchannel).requestConnection();

  verify(mockSubchannel, times(2)).requestConnection();
}
 
Example #7
Source File: OrcaOobUtilTest.java    From grpc-java with Apache License 2.0 6 votes vote down vote up
@Test
public void reportingNotStartedUntilConfigured() {
  createSubchannel(orcaHelperWrapper.asHelper(), 0, Attributes.EMPTY);
  deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
  verify(mockStateListeners[0])
      .onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));

  assertThat(orcaServiceImps[0].calls).isEmpty();
  assertThat(subchannels[0].logs).isEmpty();
  setOrcaReportConfig(orcaHelperWrapper, SHORT_INTERVAL_CONFIG);
  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.peek().request)
      .isEqualTo(buildOrcaRequestFromConfig(SHORT_INTERVAL_CONFIG));
}
 
Example #8
Source File: PickFirstLoadBalancerTest.java    From grpc-nebula-java with Apache License 2.0 6 votes vote down vote up
@Test
public void nameResolutionErrorWithStateChanges() throws Exception {
  InOrder inOrder = inOrder(mockHelper);

  loadBalancer.handleSubchannelState(mockSubchannel,
      ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE));
  Status error = Status.NOT_FOUND.withDescription("nameResolutionError");
  loadBalancer.handleNameResolutionError(error);
  inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());

  PickResult pickResult = pickerCaptor.getValue().pickSubchannel(mockArgs);
  assertEquals(null, pickResult.getSubchannel());
  assertEquals(error, pickResult.getStatus());

  loadBalancer.handleSubchannelState(mockSubchannel, ConnectivityStateInfo.forNonError(READY));
  Status error2 = Status.NOT_FOUND.withDescription("nameResolutionError2");
  loadBalancer.handleNameResolutionError(error2);
  inOrder.verify(mockHelper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());

  pickResult = pickerCaptor.getValue().pickSubchannel(mockArgs);
  assertEquals(null, pickResult.getSubchannel());
  assertEquals(error2, pickResult.getStatus());

  verifyNoMoreInteractions(mockHelper);
}
 
Example #9
Source File: AgentClientMock.java    From pinpoint with Apache License 2.0 6 votes vote down vote up
@Override
public void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
    ConnectivityState currentState = stateInfo.getState();
    if (subchannel != this.subchannel || currentState == SHUTDOWN) {
        return;
    }

    PickResult pickResult;
    switch (currentState) {
        case CONNECTING:
            pickResult = PickResult.withNoResult();
            break;
        case READY:
        case IDLE:
            pickResult = PickResult.withSubchannel(subchannel);
            break;
        case TRANSIENT_FAILURE:
            pickResult = PickResult.withError(stateInfo.getStatus());
            break;
        default:
            throw new IllegalArgumentException("Unsupported state:" + currentState);
    }

    helper.updateBalancingState(currentState, new Picker(pickResult));
}
 
Example #10
Source File: OrcaOobUtilTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void updateReportingIntervalBeforeSubchannelReady() {
  createSubchannel(orcaHelperWrapper.asHelper(), 0, Attributes.EMPTY);
  setOrcaReportConfig(orcaHelperWrapper, SHORT_INTERVAL_CONFIG);
  deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
  verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));

  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.poll().request)
      .isEqualTo(buildOrcaRequestFromConfig(SHORT_INTERVAL_CONFIG));
}
 
Example #11
Source File: OrcaOobUtilTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void updateReportingIntervalWhenRpcActive() {
  // Sets report interval before creating a Subchannel, reporting starts right after suchannel
  // state becomes READY.
  setOrcaReportConfig(orcaHelperWrapper, MEDIUM_INTERVAL_CONFIG);
  createSubchannel(orcaHelperWrapper.asHelper(), 0, Attributes.EMPTY);
  deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
  verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));

  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.peek().request)
      .isEqualTo(buildOrcaRequestFromConfig(MEDIUM_INTERVAL_CONFIG));

  // Make reporting less frequent.
  setOrcaReportConfig(orcaHelperWrapper, LONG_INTERVAL_CONFIG);
  assertThat(orcaServiceImps[0].calls.poll().cancelled).isTrue();
  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.peek().request)
      .isEqualTo(buildOrcaRequestFromConfig(LONG_INTERVAL_CONFIG));

  // Configuring with the same report interval again does not restart ORCA RPC.
  setOrcaReportConfig(orcaHelperWrapper, LONG_INTERVAL_CONFIG);
  assertThat(orcaServiceImps[0].calls.peek().cancelled).isFalse();
  assertThat(subchannels[0].logs).isEmpty();

  // Make reporting more frequent.
  setOrcaReportConfig(orcaHelperWrapper, SHORT_INTERVAL_CONFIG);
  assertThat(orcaServiceImps[0].calls.poll().cancelled).isTrue();
  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.poll().request)
      .isEqualTo(buildOrcaRequestFromConfig(SHORT_INTERVAL_CONFIG));
}
 
Example #12
Source File: GracefulSwitchLoadBalancerTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Deprecated
@Test
public void handleSubchannelState_shouldThrow() {
  gracefulSwitchLb.switchTo(lbProviders.get(lbPolicies[0]));
  Subchannel subchannel = mock(Subchannel.class);
  ConnectivityStateInfo connectivityStateInfo = ConnectivityStateInfo.forNonError(READY);
  thrown.expect(UnsupportedOperationException.class);
  gracefulSwitchLb.handleSubchannelState(subchannel, connectivityStateInfo);
}
 
Example #13
Source File: AutoConfiguredLoadBalancerFactoryTest.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Test
public void forwardsCalls() {
  AutoConfiguredLoadBalancer lb =
      (AutoConfiguredLoadBalancer) 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);
}
 
Example #14
Source File: GrpcRouteRoundRobinLbFactory.java    From saluki with Apache License 2.0 5 votes vote down vote up
/**
 * If all subchannels are TRANSIENT_FAILURE, return the Status associated with an arbitrary
 * subchannel otherwise, return null.
 */
@Nullable
private Status getAggregatedError() {
  Status status = null;
  for (Subchannel subchannel : getSubchannels()) {
    ConnectivityStateInfo stateInfo = getSubchannelStateInfoRef(subchannel).get();
    if (stateInfo.getState() != TRANSIENT_FAILURE) {
      return null;
    }
    status = stateInfo.getStatus();
  }
  return status;
}
 
Example #15
Source File: OrcaOobUtil.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Override
public void onSubchannelState(ConnectivityStateInfo newState) {
  if (Objects.equal(state.getState(), READY) && !Objects.equal(newState.getState(), READY)) {
    // A connection was lost.  We will reset disabled flag because ORCA service
    // may be available on the new connection.
    disabled = false;
  }
  if (Objects.equal(newState.getState(), SHUTDOWN)) {
    orcaHelper.orcaStates.remove(this);
  }
  state = newState;
  adjustOrcaReporting();
  // Propagate subchannel state update to downstream listeners.
  stateListener.onSubchannelState(newState);
}
 
Example #16
Source File: RoundRobinLoadBalancerTest.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Test
public void noStickinessEnabled_withStickyHeader() {
  loadBalancer.handleResolvedAddressGroups(servers, Attributes.EMPTY);
  for (Subchannel subchannel : subchannels.values()) {
    loadBalancer.handleSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
  }
  verify(mockHelper, times(4))
      .updateBalancingState(any(ConnectivityState.class), pickerCaptor.capture());
  SubchannelPicker picker = pickerCaptor.getValue();

  Key<String> stickinessKey = Key.of("my-sticky-key", Metadata.ASCII_STRING_MARSHALLER);
  Metadata headerWithStickinessValue = new Metadata();
  headerWithStickinessValue.put(stickinessKey, "my-sticky-value");
  doReturn(headerWithStickinessValue).when(mockArgs).getHeaders();

  List<Subchannel> allSubchannels = getList(picker);
  Subchannel sc1 = picker.pickSubchannel(mockArgs).getSubchannel();
  Subchannel sc2 = picker.pickSubchannel(mockArgs).getSubchannel();
  Subchannel sc3 = picker.pickSubchannel(mockArgs).getSubchannel();
  Subchannel sc4 = picker.pickSubchannel(mockArgs).getSubchannel();

  assertEquals(nextSubchannel(sc1, allSubchannels), sc2);
  assertEquals(nextSubchannel(sc2, allSubchannels), sc3);
  assertEquals(nextSubchannel(sc3, allSubchannels), sc1);
  assertEquals(sc4, sc1);

  assertNull(loadBalancer.getStickinessMapForTest());
}
 
Example #17
Source File: RoundRobinLoadBalancerTest.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Test
public void stickinessEnabled_withStickyHeader() {
  Map<String, Object> serviceConfig = new HashMap<String, Object>();
  serviceConfig.put("stickinessMetadataKey", "my-sticky-key");
  Attributes attributes = Attributes.newBuilder()
      .set(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG, serviceConfig).build();
  loadBalancer.handleResolvedAddressGroups(servers, attributes);
  for (Subchannel subchannel : subchannels.values()) {
    loadBalancer.handleSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
  }
  verify(mockHelper, times(4))
      .updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
  SubchannelPicker picker = pickerCaptor.getValue();

  Key<String> stickinessKey = Key.of("my-sticky-key", Metadata.ASCII_STRING_MARSHALLER);
  Metadata headerWithStickinessValue = new Metadata();
  headerWithStickinessValue.put(stickinessKey, "my-sticky-value");
  doReturn(headerWithStickinessValue).when(mockArgs).getHeaders();

  Subchannel sc1 = picker.pickSubchannel(mockArgs).getSubchannel();
  assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
  assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
  assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
  assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());

  verify(mockArgs, atLeast(4)).getHeaders();
  assertNotNull(loadBalancer.getStickinessMapForTest());
  assertThat(loadBalancer.getStickinessMapForTest()).hasSize(1);
}
 
Example #18
Source File: GrpclbState.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo newState) {
  if (newState.getState() == SHUTDOWN || !subchannels.values().contains(subchannel)) {
    return;
  }
  if (newState.getState() == IDLE) {
    subchannel.requestConnection();
  }
  subchannel.getAttributes().get(STATE_INFO).set(newState);
  maybeUseFallbackBackends();
  maybeUpdatePicker();
}
 
Example #19
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private void gotoState(ConnectivityStateInfo newState) {
  checkState(subchannel != null, "init() not called");
  if (!Objects.equal(concludedState, newState)) {
    concludedState = newState;
    stateListener.onSubchannelState(concludedState);
  }
}
 
Example #20
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Override
public void handleSubchannelState(
    Subchannel subchannel, ConnectivityStateInfo stateInfo) {
  HealthCheckState hcState =
      checkNotNull(subchannel.getAttributes().get(KEY_HEALTH_CHECK_STATE), "hcState");
  hcState.updateRawState(stateInfo);

  if (Objects.equal(stateInfo.getState(), SHUTDOWN)) {
    helper.hcStates.remove(hcState);
  }
}
 
Example #21
Source File: GrpclbState.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
GrpclbState(
    GrpclbConfig config,
    Helper helper,
    SubchannelPool subchannelPool,
    TimeProvider time,
    Stopwatch stopwatch,
    BackoffPolicy.Provider backoffPolicyProvider) {
  this.config = checkNotNull(config, "config");
  this.helper = checkNotNull(helper, "helper");
  this.syncContext = checkNotNull(helper.getSynchronizationContext(), "syncContext");
  if (config.getMode() == Mode.ROUND_ROBIN) {
    this.subchannelPool = checkNotNull(subchannelPool, "subchannelPool");
    subchannelPool.registerListener(
        new PooledSubchannelStateListener() {
          @Override
          public void onSubchannelState(
              Subchannel subchannel, ConnectivityStateInfo newState) {
            handleSubchannelState(subchannel, newState);
          }
        });
  } else {
    this.subchannelPool = null;
  }
  this.time = checkNotNull(time, "time provider");
  this.stopwatch = checkNotNull(stopwatch, "stopwatch");
  this.timerService = checkNotNull(helper.getScheduledExecutorService(), "timerService");
  this.backoffPolicyProvider = checkNotNull(backoffPolicyProvider, "backoffPolicyProvider");
  if (config.getServiceName() != null) {
    this.serviceName = config.getServiceName();
  } else {
    this.serviceName = checkNotNull(helper.getAuthority(), "helper returns null authority");
  }
  this.logger = checkNotNull(helper.getChannelLogger(), "logger");
}
 
Example #22
Source File: RoundRobinLoadBalancerTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void pickAfterStateChange() throws Exception {
  InOrder inOrder = inOrder(mockHelper);
  loadBalancer.handleResolvedAddresses(
      ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(Attributes.EMPTY)
          .build());
  Subchannel subchannel = loadBalancer.getSubchannels().iterator().next();
  Ref<ConnectivityStateInfo> subchannelStateInfo = subchannel.getAttributes().get(
      STATE_INFO);

  inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), isA(EmptyPicker.class));
  assertThat(subchannelStateInfo.value).isEqualTo(ConnectivityStateInfo.forNonError(IDLE));

  deliverSubchannelState(subchannel,
      ConnectivityStateInfo.forNonError(READY));
  inOrder.verify(mockHelper).updateBalancingState(eq(READY), pickerCaptor.capture());
  assertThat(pickerCaptor.getValue()).isInstanceOf(ReadyPicker.class);
  assertThat(subchannelStateInfo.value).isEqualTo(
      ConnectivityStateInfo.forNonError(READY));

  Status error = Status.UNKNOWN.withDescription("¯\\_(ツ)_//¯");
  deliverSubchannelState(subchannel,
      ConnectivityStateInfo.forTransientFailure(error));
  assertThat(subchannelStateInfo.value.getState()).isEqualTo(TRANSIENT_FAILURE);
  assertThat(subchannelStateInfo.value.getStatus()).isEqualTo(error);
  inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
  assertThat(pickerCaptor.getValue()).isInstanceOf(EmptyPicker.class);

  deliverSubchannelState(subchannel,
      ConnectivityStateInfo.forNonError(IDLE));
  assertThat(subchannelStateInfo.value.getState()).isEqualTo(TRANSIENT_FAILURE);
  assertThat(subchannelStateInfo.value.getStatus()).isEqualTo(error);

  verify(subchannel, times(2)).requestConnection();
  verify(mockHelper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
  verifyNoMoreInteractions(mockHelper);
}
 
Example #23
Source File: InternalSubchannel.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
/**
 * Only called after all addresses attempted and failed (TRANSIENT_FAILURE).
 * @param status the causal status when the channel begins transition to
 *     TRANSIENT_FAILURE.
 */
private void scheduleBackoff(final Status status) {
  syncContext.throwIfNotInThisSynchronizationContext();

  class EndOfCurrentBackoff implements Runnable {
    @Override
    public void run() {
      reconnectTask = null;
      channelLogger.log(ChannelLogLevel.INFO, "CONNECTING after backoff");
      gotoNonErrorState(CONNECTING);
      startNewTransport();
    }
  }

  gotoState(ConnectivityStateInfo.forTransientFailure(status));
  if (reconnectPolicy == null) {
    reconnectPolicy = backoffPolicyProvider.get();
  }
  long delayNanos =
      reconnectPolicy.nextBackoffNanos() - connectingTimer.elapsed(TimeUnit.NANOSECONDS);
  channelLogger.log(
      ChannelLogLevel.INFO,
      "TRANSIENT_FAILURE ({0}). Will reconnect after {1} ns",
      printShortStatus(status), delayNanos);
  Preconditions.checkState(reconnectTask == null, "previous reconnectTask is not done");
  reconnectTask = syncContext.schedule(
      new EndOfCurrentBackoff(),
      delayNanos,
      TimeUnit.NANOSECONDS,
      scheduledExecutor);
}
 
Example #24
Source File: OrcaOobUtilTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void updateReportingIntervalWhenRpcPendingRetry() {
  createSubchannel(orcaHelperWrapper.asHelper(), 0, Attributes.EMPTY);
  setOrcaReportConfig(orcaHelperWrapper, SHORT_INTERVAL_CONFIG);
  deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
  verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));

  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.peek().request)
      .isEqualTo(buildOrcaRequestFromConfig(SHORT_INTERVAL_CONFIG));

  // Server closes the RPC without response, client will retry with backoff.
  assertThat(fakeClock.getPendingTasks()).isEmpty();
  orcaServiceImps[0].calls.poll().responseObserver.onCompleted();
  assertLog(subchannels[0].logs,
      "DEBUG: ORCA reporting stream closed with " + Status.OK + ", backoff in 11"
          + " ns");
  assertThat(fakeClock.getPendingTasks()).hasSize(1);
  assertThat(orcaServiceImps[0].calls).isEmpty();

  // Make reporting less frequent.
  setOrcaReportConfig(orcaHelperWrapper, LONG_INTERVAL_CONFIG);
  // Retry task will be canceled and restarts new RPC immediately.
  assertThat(fakeClock.getPendingTasks()).isEmpty();
  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.peek().request)
      .isEqualTo(buildOrcaRequestFromConfig(LONG_INTERVAL_CONFIG));
}
 
Example #25
Source File: PickFirstLoadBalancer.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
private void processSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
  ConnectivityState currentState = stateInfo.getState();
  if (currentState == SHUTDOWN) {
    return;
  }

  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);
}
 
Example #26
Source File: OrcaOobUtilTest.java    From grpc-java with Apache License 2.0 5 votes vote down vote up
@Test
public void updateReportingIntervalBeforeCreatingSubchannel() {
  setOrcaReportConfig(orcaHelperWrapper, SHORT_INTERVAL_CONFIG);
  createSubchannel(orcaHelperWrapper.asHelper(), 0, Attributes.EMPTY);
  deliverSubchannelState(0, ConnectivityStateInfo.forNonError(READY));
  verify(mockStateListeners[0]).onSubchannelState(eq(ConnectivityStateInfo.forNonError(READY)));

  assertThat(orcaServiceImps[0].calls).hasSize(1);
  assertLog(subchannels[0].logs,
      "DEBUG: Starting ORCA reporting for " + subchannels[0].getAllAddresses());
  assertThat(orcaServiceImps[0].calls.poll().request)
      .isEqualTo(buildOrcaRequestFromConfig(SHORT_INTERVAL_CONFIG));
}
 
Example #27
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
private void gotoState(ConnectivityStateInfo newState) {
  checkState(subchannel != null, "init() not called");
  if (!helperImpl.balancerShutdown && !Objects.equal(concludedState, newState)) {
    concludedState = newState;
    delegate.handleSubchannelState(subchannel, concludedState);
  }
}
 
Example #28
Source File: HealthCheckingLoadBalancerFactory.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Override
public void shutdown() {
  super.shutdown();
  helper.balancerShutdown = true;
  for (HealthCheckState hcState : helper.hcStates) {
    // ManagedChannel will stop calling handleSubchannelState() after shutdown() is called,
    // which is required by LoadBalancer API semantics. We need to deliver the final SHUTDOWN
    // signal to health checkers so that they can cancel the streams.
    hcState.updateRawState(ConnectivityStateInfo.forNonError(SHUTDOWN));
  }
  helper.hcStates.clear();
}
 
Example #29
Source File: PickFirstLoadBalancer.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
@Override
public void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
  ConnectivityState currentState = stateInfo.getState();
  if (currentState == SHUTDOWN) {
    return;
  }

  EquivalentAddressGroup addressGroup = subchannel.getAddresses();
  Subchannel theSubchannel = subchannels.get(addressGroup);
  if (theSubchannel == null) {
    return;
  }

  if (theSubchannel != currentSubchannel) {
    return;
  }

  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);
}
 
Example #30
Source File: GrpclbLoadBalancerTest.java    From grpc-nebula-java with Apache License 2.0 5 votes vote down vote up
private void deliverSubchannelState(
    final Subchannel subchannel, final ConnectivityStateInfo newState) {
  syncContext.execute(new Runnable() {
      @Override
      public void run() {
        balancer.handleSubchannelState(subchannel, newState);
      }
    });
}