@Test public void inUseState() { SocketAddress addr = mock(SocketAddress.class); createInternalSubchannel(addr); internalSubchannel.obtainActiveTransport(); MockClientTransportInfo t0 = transports.poll(); t0.listener.transportReady(); assertExactCallbackInvokes("onStateChange:CONNECTING", "onStateChange:READY"); t0.listener.transportInUse(true); assertExactCallbackInvokes("onInUse"); t0.listener.transportInUse(false); assertExactCallbackInvokes("onNotInUse"); t0.listener.transportInUse(true); assertExactCallbackInvokes("onInUse"); t0.listener.transportShutdown(Status.UNAVAILABLE); assertExactCallbackInvokes("onStateChange:IDLE"); assertNull(internalSubchannel.obtainActiveTransport()); MockClientTransportInfo t1 = transports.poll(); t1.listener.transportReady(); assertExactCallbackInvokes("onStateChange:CONNECTING", "onStateChange:READY"); t1.listener.transportInUse(true); assertNoCallbackInvoke(); t1.listener.transportInUse(false); assertNoCallbackInvoke(); t0.listener.transportInUse(false); assertExactCallbackInvokes("onNotInUse"); }
@Nullable ClientTransport obtainActiveTransport() { ClientTransport savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } try { synchronized (lock) { savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } if (state.getState() == IDLE) { channelLogger.log(ChannelLogLevel.INFO, "CONNECTING as requested"); gotoNonErrorState(CONNECTING); startNewTransport(); } } } finally { syncContext.drain(); } return null; }
InternalSubchannel implements InternalInstrumented<ChannelStats> { @Nullable ClientTransport obtainActiveTransport() { ClientTransport savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } try { synchronized (lock) { savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } if (state.getState() == IDLE) { channelLogger.log(ChannelLogLevel.INFO, "CONNECTING as requested"); gotoNonErrorState(CONNECTING); startNewTransport(); } } } finally { syncContext.drain(); } return null; } }
InternalSubchannel implements InternalInstrumented<ChannelStats> { @Nullable ClientTransport obtainActiveTransport() { ClientTransport savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } try { synchronized (lock) { savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } if (state.getState() == IDLE) { channelLogger.log(ChannelLogLevel.INFO, "CONNECTING as requested"); gotoNonErrorState(CONNECTING); startNewTransport(); } } } finally { syncContext.drain(); } return null; } InternalSubchannel(List<EquivalentAddressGroup> addressGroups, String authority, String userAgent,
      BackoffPolicy.Provider backoffPolicyProvider,
      ClientTransportFactory transportFactory, ScheduledExecutorService scheduledExecutor,
      Supplier<Stopwatch> stopwatchSupplier, SynchronizationContext syncContext, Callback callback,
      InternalChannelz channelz, CallTracer callsTracer, ChannelTracer channelTracer,
      InternalLogId logId, TimeProvider timeProvider); }
InternalSubchannel implements InternalInstrumented<ChannelStats> { @Nullable ClientTransport obtainActiveTransport() { ClientTransport savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } try { synchronized (lock) { savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } if (state.getState() == IDLE) { channelLogger.log(ChannelLogLevel.INFO, "CONNECTING as requested"); gotoNonErrorState(CONNECTING); startNewTransport(); } } } finally { syncContext.drain(); } return null; } InternalSubchannel(List<EquivalentAddressGroup> addressGroups, String authority, String userAgent,
      BackoffPolicy.Provider backoffPolicyProvider,
      ClientTransportFactory transportFactory, ScheduledExecutorService scheduledExecutor,
      Supplier<Stopwatch> stopwatchSupplier, SynchronizationContext syncContext, Callback callback,
      InternalChannelz channelz, CallTracer callsTracer, ChannelTracer channelTracer,
      InternalLogId logId, TimeProvider timeProvider); void updateAddresses(List<EquivalentAddressGroup> newAddressGroups); void shutdown(Status reason); @Override String toString(); @Override InternalLogId getLogId(); @Override ListenableFuture<ChannelStats> getStats(); }
InternalSubchannel implements InternalInstrumented<ChannelStats> { @Nullable ClientTransport obtainActiveTransport() { ClientTransport savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } try { synchronized (lock) { savedTransport = activeTransport; if (savedTransport != null) { return savedTransport; } if (state.getState() == IDLE) { channelLogger.log(ChannelLogLevel.INFO, "CONNECTING as requested"); gotoNonErrorState(CONNECTING); startNewTransport(); } } } finally { syncContext.drain(); } return null; } InternalSubchannel(List<EquivalentAddressGroup> addressGroups, String authority, String userAgent,
      BackoffPolicy.Provider backoffPolicyProvider,
      ClientTransportFactory transportFactory, ScheduledExecutorService scheduledExecutor,
      Supplier<Stopwatch> stopwatchSupplier, SynchronizationContext syncContext, Callback callback,
      InternalChannelz channelz, CallTracer callsTracer, ChannelTracer channelTracer,
      InternalLogId logId, TimeProvider timeProvider); void updateAddresses(List<EquivalentAddressGroup> newAddressGroups); void shutdown(Status reason); @Override String toString(); @Override InternalLogId getLogId(); @Override ListenableFuture<ChannelStats> getStats();  }