private List<IdleChannel> expiredChannels(ConcurrentLinkedDeque<IdleChannel> partition, long now) { // lazy create List<IdleChannel> idleTimeoutChannels = null; for (IdleChannel idleChannel : partition) { boolean isIdleTimeoutExpired = isIdleTimeoutExpired(idleChannel, now); boolean isRemotelyClosed = !Channels.isChannelActive(idleChannel.channel); boolean isTtlExpired = isTtlExpired(idleChannel.channel, now); if (isIdleTimeoutExpired || isRemotelyClosed || isTtlExpired) { LOGGER.debug("Adding Candidate expired Channel {} isIdleTimeoutExpired={} isRemotelyClosed={} isTtlExpired={}", idleChannel.channel, isIdleTimeoutExpired, isRemotelyClosed, isTtlExpired); if (idleTimeoutChannels == null) idleTimeoutChannels = new ArrayList<>(1); idleTimeoutChannels.add(idleChannel); } } return idleTimeoutChannels != null ? idleTimeoutChannels : Collections.emptyList(); }
/** * {@inheritDoc} */ public Channel poll(Object partitionKey) { IdleChannel idleChannel = null; ConcurrentLinkedDeque<IdleChannel> partition = partitions.get(partitionKey); if (partition != null) { while (idleChannel == null) { idleChannel = poolLeaseStrategy.lease(partition); if (idleChannel == null) // pool is empty break; else if (!Channels.isChannelActive(idleChannel.channel)) { idleChannel = null; LOGGER.trace("Channel is inactive, probably remotely closed!"); } else if (!idleChannel.takeOwnership()) { idleChannel = null; LOGGER.trace("Couldn't take ownership of channel, probably in the process of being expired!"); } } } return idleChannel != null ? idleChannel.channel : null; }
/** * Return true if the {@link Future} can be recovered. There is some scenario * where a connection can be closed by an unexpected IOException, and in some * situation we can recover from that exception. * * @return true if that {@link Future} cannot be recovered. */ public boolean isReplayPossible() { return !isDone() && !(Channels.isChannelActive(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && inAuth == 0 && inProxyAuth == 0; }
private Channel getOpenChannel(NettyResponseFuture<?> future, Request request, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.isReuseChannel() && Channels.isChannelActive(future.channel())) { return future.channel(); } else { return pollPooledChannel(request, proxyServer, asyncHandler); } }
/** * We know for sure if we have to force to connect or not, so we can build the * HttpRequest right away This reduces the probability of having a pooled * channel closed by the server by the time we build the request */ private <T> ListenableFuture<T> sendRequestWithCertainForceConnect(Request request, AsyncHandler<T> asyncHandler, NettyResponseFuture<T> future, ProxyServer proxyServer, boolean performConnectRequest) { NettyResponseFuture<T> newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, proxyServer, performConnectRequest); Channel channel = getOpenChannel(future, request, proxyServer, asyncHandler); return Channels.isChannelActive(channel) ? sendRequestWithOpenChannel(newFuture, asyncHandler, channel) : sendRequestWithNewChannel(request, proxyServer, newFuture, asyncHandler); }
/** * Using CONNECT depends on wither we can fetch a valid channel or not Loop * until we get a valid channel from the pool and it's still valid once the * request is built @ */ private <T> ListenableFuture<T> sendRequestThroughProxy(Request request, AsyncHandler<T> asyncHandler, NettyResponseFuture<T> future, ProxyServer proxyServer) { NettyResponseFuture<T> newFuture = null; for (int i = 0; i < 3; i++) { Channel channel = getOpenChannel(future, request, proxyServer, asyncHandler); if (channel == null) { // pool is empty break; } if (newFuture == null) { newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, proxyServer, false); } if (Channels.isChannelActive(channel)) { // if the channel is still active, we can use it, // otherwise, channel was closed by the time we computed the request, try again return sendRequestWithOpenChannel(newFuture, asyncHandler, channel); } } // couldn't poll an active channel newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, proxyServer, true); return sendRequestWithNewChannel(request, proxyServer, newFuture, asyncHandler); }
if (Channels.isChannelActive(channel)) { writeRequest(future, channel); } else {
if (!Channels.isChannelActive(channel)) return; if (Channels.isChannelActive(channel)) { scheduleReadTimeout(future);