private List<IdleChannel> expiredChannels(ConcurrentLinkedQueue<IdleChannel> partition, long now) { // lazy create List<IdleChannel> idleTimeoutChannels = null; for (IdleChannel idleChannel : partition) { if (isTTLExpired(idleChannel.channel, now) || isIdleTimeoutExpired(idleChannel, now) || !Channels.isChannelValid(idleChannel.channel)) { LOGGER.debug("Adding Candidate expired Channel {}", idleChannel.channel); if (idleTimeoutChannels == null) idleTimeoutChannels = new ArrayList<>(); idleTimeoutChannels.add(idleChannel); } } return idleTimeoutChannels != null ? idleTimeoutChannels : Collections.<IdleChannel> emptyList(); }
private List<IdleChannel> expiredChannels(ConcurrentLinkedQueue<IdleChannel> partition, long now) { // lazy create List<IdleChannel> idleTimeoutChannels = null; for (IdleChannel idleChannel : partition) { if (isTTLExpired(idleChannel.channel, now) || isIdleTimeoutExpired(idleChannel, now) || !Channels.isChannelValid(idleChannel.channel)) { LOGGER.debug("Adding Candidate expired Channel {}", idleChannel.channel); if (idleTimeoutChannels == null) idleTimeoutChannels = new ArrayList<>(); idleTimeoutChannels.add(idleChannel); } } return idleTimeoutChannels != null ? idleTimeoutChannels : Collections.<IdleChannel> emptyList(); }
public Channel poll(Object partitionKey) { IdleChannel idleChannel = null; ConcurrentLinkedQueue<IdleChannel> partition = partitions.get(partitionKey); if (partition != null) { while (idleChannel == null) { idleChannel = partition.poll(); if (idleChannel == null) // pool is empty break; else if (!Channels.isChannelValid(idleChannel.channel)) { idleChannel = null; LOGGER.trace("Channel not connected or not opened, probably remotely closed!"); } } } return idleChannel != null ? idleChannel.channel : null; }
public Channel poll(Object partitionKey) { IdleChannel idleChannel = null; ConcurrentLinkedQueue<IdleChannel> partition = partitions.get(partitionKey); if (partition != null) { while (idleChannel == null) { idleChannel = partition.poll(); if (idleChannel == null) // pool is empty break; else if (!Channels.isChannelValid(idleChannel.channel)) { idleChannel = null; LOGGER.trace("Channel not connected or not opened, probably remotely closed!"); } } } 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 canBeReplayed() { return !isDone() && canRetry() && !(Channels.isChannelValid(channel) && !uri.getScheme().equalsIgnoreCase("https")) && !isInAuth(); }
/** * 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 canBeReplayed() { return !isDone() && canRetry() && !(Channels.isChannelValid(channel) && !uri.getScheme().equalsIgnoreCase("https")) && !isInAuth(); }
/** * 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 canBeReplayed() { return !isDone() && canRetry() && !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !isInAuth(); }
/** * 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 canBeReplayed() { return !isDone() && canRetry() && !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !isInAuth(); }
private Channel getCachedChannel(NettyResponseFuture<?> future, Request request, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.reuseChannel() && Channels.isChannelValid(future.channel())) return future.channel(); else return pollAndVerifyCachedChannel(request, proxyServer, asyncHandler); }
private Channel getCachedChannel(NettyResponseFuture<?> future, Request request, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.reuseChannel() && Channels.isChannelValid(future.channel())) return future.channel(); else return pollAndVerifyCachedChannel(request, proxyServer, asyncHandler); }
private Channel getCachedChannel(NettyResponseFuture<?> future, Uri uri, ConnectionPoolPartitioning partitioning, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.reuseChannel() && Channels.isChannelValid(future.channel())) return future.channel(); else return pollAndVerifyCachedChannel(uri, proxyServer, partitioning, asyncHandler); }
private Channel getCachedChannel(NettyResponseFuture<?> future, Uri uri, ConnectionPoolPartitioning partitioning, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.reuseChannel() && Channels.isChannelValid(future.channel())) return future.channel(); else return pollAndVerifyCachedChannel(uri, proxyServer, partitioning, 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 */ @SuppressWarnings("unused") private <T> ListenableFuture<T> sendRequestThroughSslProxy(// Request request,// AsyncHandler<T> asyncHandler,// NettyResponseFuture<T> future,// boolean reclaimCache,// Uri uri,// ProxyServer proxyServer) throws IOException { NettyResponseFuture<T> newFuture = null; for (int i = 0; i < 3; i++) { Channel channel = getCachedChannel(future, uri, request.getConnectionPoolPartitioning(), proxyServer, asyncHandler); if (Channels.isChannelValid(channel)) if (newFuture == null) newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, uri, proxyServer, false); if (Channels.isChannelValid(channel)) // if the channel is still active, we can use it, otherwise try gain return sendRequestWithCachedChannel(request, uri, proxyServer, newFuture, asyncHandler, channel); else // pool is empty break; } newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, uri, proxyServer, true); return sendRequestWithNewChannel(request, uri, proxyServer, true, newFuture, asyncHandler, reclaimCache); }
/** * 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,// boolean reclaimCache,// ProxyServer proxyServer,// boolean useProxy,// boolean forceConnect) { NettyResponseFuture<T> newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, proxyServer, forceConnect); Channel channel = getCachedChannel(future, request, proxyServer, asyncHandler); if (Channels.isChannelValid(channel)) return sendRequestWithCachedChannel(request, proxyServer, newFuture, asyncHandler, channel); else return sendRequestWithNewChannel(request, proxyServer, useProxy, newFuture, asyncHandler, reclaimCache); }
/** * 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,// boolean reclaimCache,// ProxyServer proxyServer,// boolean useProxy,// boolean forceConnect) { NettyResponseFuture<T> newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, proxyServer, forceConnect); Channel channel = getCachedChannel(future, request, proxyServer, asyncHandler); if (Channels.isChannelValid(channel)) return sendRequestWithCachedChannel(request, proxyServer, newFuture, asyncHandler, channel); else return sendRequestWithNewChannel(request, proxyServer, useProxy, newFuture, asyncHandler, reclaimCache); }
/** * 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,// boolean reclaimCache,// Uri uri,// ProxyServer proxyServer,// boolean useProxy,// boolean forceConnect) throws IOException { NettyResponseFuture<T> newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, uri, proxyServer, forceConnect); Channel channel = getCachedChannel(future, uri, request.getConnectionPoolPartitioning(), proxyServer, asyncHandler); if (Channels.isChannelValid(channel)) return sendRequestWithCachedChannel(request, uri, proxyServer, newFuture, asyncHandler, channel); else return sendRequestWithNewChannel(request, uri, proxyServer, useProxy, newFuture, asyncHandler, reclaimCache); }
/** * 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,// boolean reclaimCache,// Uri uri,// ProxyServer proxyServer,// boolean useProxy,// boolean forceConnect) throws IOException { NettyResponseFuture<T> newFuture = newNettyRequestAndResponseFuture(request, asyncHandler, future, uri, proxyServer, forceConnect); Channel channel = getCachedChannel(future, uri, request.getConnectionPoolPartitioning(), proxyServer, asyncHandler); if (Channels.isChannelValid(channel)) return sendRequestWithCachedChannel(request, uri, proxyServer, newFuture, asyncHandler, channel); else return sendRequestWithNewChannel(request, uri, proxyServer, useProxy, newFuture, asyncHandler, reclaimCache); }
private <T> ListenableFuture<T> sendRequestWithCachedChannel(Request request, ProxyServer proxy, NettyResponseFuture<T> future, AsyncHandler<T> asyncHandler, Channel channel) { if (asyncHandler instanceof AsyncHandlerExtensions) AsyncHandlerExtensions.class.cast(asyncHandler).onConnectionPooled(channel); future.setState(NettyResponseFuture.STATE.POOLED); future.attachChannel(channel, false); LOGGER.debug("Using cached Channel {} for {} '{}'", channel, future.getNettyRequest().getHttpRequest().getMethod(), future.getNettyRequest().getHttpRequest().getUri()); if (Channels.isChannelValid(channel)) { Channels.setAttribute(channel, future); writeRequest(future, channel); } else { // bad luck, the channel was closed in-between // there's a very good chance onClose was already notified but the // future wasn't already registered handleUnexpectedClosedChannel(channel, future); } return future; }
private <T> ListenableFuture<T> sendRequestWithCachedChannel(Request request, ProxyServer proxy, NettyResponseFuture<T> future, AsyncHandler<T> asyncHandler, Channel channel) { if (asyncHandler instanceof AsyncHandlerExtensions) AsyncHandlerExtensions.class.cast(asyncHandler).onConnectionPooled(channel); future.setState(NettyResponseFuture.STATE.POOLED); future.attachChannel(channel, false); LOGGER.debug("Using cached Channel {} for {} '{}'", channel, future.getNettyRequest().getHttpRequest().getMethod(), future.getNettyRequest().getHttpRequest().getUri()); if (Channels.isChannelValid(channel)) { Channels.setAttribute(channel, future); writeRequest(future, channel); } else { // bad luck, the channel was closed in-between // there's a very good chance onClose was already notified but the // future wasn't already registered handleUnexpectedClosedChannel(channel, future); } return future; }
public <T> void writeRequest(NettyResponseFuture<T> future, Channel channel) { NettyRequest nettyRequest = future.getNettyRequest(); HttpRequest httpRequest = nettyRequest.getHttpRequest(); AsyncHandler<T> handler = future.getAsyncHandler(); // if the channel is dead because it was pooled and the remote // server decided to close it, // we just let it go and the channelInactive do its work if (!Channels.isChannelValid(channel)) return; try { if (handler instanceof TransferCompletionHandler) configureTransferAdapter(handler, httpRequest); if (!future.isHeadersAlreadyWrittenOnContinue()) { if (future.getAsyncHandler() instanceof AsyncHandlerExtensions) AsyncHandlerExtensions.class.cast(future.getAsyncHandler()).onSendRequest(nettyRequest); channel.write(httpRequest).addListener(new ProgressListener(config, future.getAsyncHandler(), future, true)); } if (!future.isDontWriteBodyBecauseExpectContinue() && httpRequest.getMethod() != HttpMethod.CONNECT && nettyRequest.getBody() != null) nettyRequest.getBody().write(channel, future); // don't bother scheduling timeouts if channel became invalid if (Channels.isChannelValid(channel)) scheduleTimeouts(future); } catch (Throwable t) { LOGGER.error("Can't write request", t); Channels.silentlyCloseChannel(channel); } }