@Override public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) throws Exception { // call super to reset the read timeout super.messageReceived(ctx, e); Channel channel = ctx.getChannel(); Object attribute = Channels.getAttribute(channel); if (attribute instanceof Callback) { Object message = e.getMessage(); Callback ac = (Callback) attribute; if (message instanceof HttpChunk) { // the AsyncCallable is to be processed on the last chunk if (HttpChunk.class.cast(message).isLast()) // process the AsyncCallable before passing the message to the protocol ac.call(); // FIXME remove attribute? } else { LOGGER.info("Received unexpected message while expecting a chunk: " + message); ac.call(); Channels.setDiscard(channel); } } else if (attribute instanceof NettyResponseFuture<?>) { NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute; protocol.handle(channel, future, e.getMessage()); } else if (attribute != DiscardEvent.INSTANCE) { // unhandled message LOGGER.debug("Orphan channel {} with attribute {} received message {}, closing", channel, attribute, e.getMessage()); Channels.silentlyCloseChannel(channel); } }
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 static void setDiscard(Channel channel) { setAttribute(channel, DiscardEvent.INSTANCE); }
private void close(Channel channel) { // FIXME pity to have to do this here Channels.setDiscard(channel); channelId2Creation.remove(channel.getId()); Channels.silentlyCloseChannel(channel); }
future.getNettyRequest().getHttpRequest().getUri()); if (Channels.isChannelValid(channel)) { Channels.setAttribute(channel, future);
@Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { if (requestSender.isClosed()) return; Channel channel = ctx.getChannel(); channelManager.removeAll(channel); try { super.channelClosed(ctx, e); } catch (Exception ex) { LOGGER.trace("super.channelClosed", ex); } Object attribute = Channels.getAttribute(channel); LOGGER.debug("Channel Closed: {} with attribute {}", channel, attribute); if (attribute instanceof Callback) { Callback callback = (Callback) attribute; Channels.setAttribute(channel, callback.future()); callback.call(); } else if (attribute instanceof NettyResponseFuture<?>) { NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute; future.touch(); if (!config.getIOExceptionFilters().isEmpty() && requestSender.applyIoExceptionFiltersAndReplayRequest(future, CHANNEL_CLOSED_EXCEPTION, channel)) return; protocol.onClose(future); requestSender.handleUnexpectedClosedChannel(channel, future); } }
public final void tryToOfferChannelToPool(Channel channel, boolean keepAlive, Object partitionKey) { if (channel.isConnected() && keepAlive && channel.isReadable()) { LOGGER.debug("Adding key: {} for channel {}", partitionKey, channel); Channels.setDiscard(channel); if (channelPool.offer(channel, partitionKey)) { if (maxConnectionsPerHostEnabled) channelId2PartitionKey.putIfAbsent(channel.getId(), partitionKey); } else { // rejected by pool closeChannel(channel); } } else { // not offered closeChannel(channel); } }
public void close() { channelPool.destroy(); openChannels.close(); for (Channel channel : openChannels) { Object attribute = Channels.getAttribute(channel); if (attribute instanceof NettyResponseFuture<?>) { NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute; future.cancelTimeouts(); } } // FIXME also shutdown in provider config.executorService().shutdown(); if (allowReleaseSocketChannelFactory) { socketChannelFactory.releaseExternalResources(); plainBootstrap.releaseExternalResources(); secureBootstrap.releaseExternalResources(); webSocketBootstrap.releaseExternalResources(); secureWebSocketBootstrap.releaseExternalResources(); } }
Object attribute = Channels.getAttribute(channel); LOGGER.info("Received unexpected message while expecting a chunk: " + message); ac.call(); Channels.setDiscard(channel);
Object attribute = Channels.getAttribute(channel); if (attribute instanceof NettyResponseFuture<?>) { future = (NettyResponseFuture<?>) attribute; if (!requestSender.applyIoExceptionFiltersAndReplayRequest(future, CHANNEL_CLOSED_EXCEPTION, channel)) Channels.silentlyCloseChannel(channel); return;
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 (nettyRequest.getBody() != null && !future.isDontWriteBodyBecauseExpectContinue() && httpRequest.getMethod() != HttpMethod.CONNECT) nettyRequest.getBody().write(channel, future, config); // 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); } }
public void attachChannel(Channel channel, boolean reuseChannel) { // future could have been cancelled first if (isDone()) { Channels.silentlyCloseChannel(channel); } this.channel = channel; this.reuseChannel = reuseChannel; }
@Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { if (requestSender.isClosed()) return; Channel channel = ctx.getChannel(); channelManager.removeAll(channel); try { super.channelClosed(ctx, e); } catch (Exception ex) { LOGGER.trace("super.channelClosed", ex); } Object attribute = Channels.getAttribute(channel); LOGGER.debug("Channel Closed: {} with attribute {}", channel, attribute); if (attribute instanceof Callback) { Callback callback = (Callback) attribute; Channels.setAttribute(channel, callback.future()); callback.call(); } else if (attribute instanceof NettyResponseFuture<?>) { NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute; future.touch(); if (!config.getIOExceptionFilters().isEmpty() && requestSender.applyIoExceptionFiltersAndReplayRequest(future, CHANNEL_CLOSED_EXCEPTION, channel)) return; protocol.onClose(channel); if (future == null || future.isDone()) channelManager.closeChannel(channel); else if (!requestSender.retry(future, ctx.getChannel())) requestSender.abort(future, REMOTELY_CLOSED_EXCEPTION); } }
Channels.setDiscard(channel); CloseWebSocketFrame closeFrame = CloseWebSocketFrame.class.cast(frame); webSocket.onClose(closeFrame.getStatusCode(), closeFrame.getReasonText());
private boolean isChannelCloseable(Channel channel) { Object attribute = Channels.getAttribute(channel); if (attribute instanceof NettyResponseFuture) { NettyResponseFuture<?> future = (NettyResponseFuture<?>) attribute; if (!future.isDone()) LOGGER.error("Future not in appropriate state %s, not closing", future); } return true; }
public void closeChannel(Channel channel) { // The channel may have already been removed from the future if a timeout occurred, and this method may be called just after. LOGGER.debug("Closing Channel {} ", channel); try { removeAll(channel); Channels.setDiscard(channel); Channels.silentlyCloseChannel(channel); } catch (Throwable t) { LOGGER.debug("Error closing a connection", t); } openChannels.remove(channel); }
@Override public boolean add(Channel channel) { // Synchronization must occur to avoid add() and close() overlap (thus potentially leaving one channel open). // This could also be done by synchronizing the method itself but using a read lock here (rather than a // synchronized() block) allows multiple concurrent calls to add(). this.lock.readLock().lock(); try { if (this.closed.get()) { // Immediately close channel, as close() was already called. Channels.silentlyCloseChannel(channel); return false; } return super.add(channel); } finally { this.lock.readLock().unlock(); } } }
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!"); } 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; }
public void drainChannelAndOffer(final Channel channel, final NettyResponseFuture<?> future, boolean keepAlive, Object partitionKey) { Channels.setAttribute(channel, newDrainCallback(future, channel, keepAlive, partitionKey)); }
private void close(Channel channel) { try { // FIXME pity to have to do this here Channels.setDiscard(channel); channelId2Creation.remove(channel.getId()); channel.close(); } catch (Throwable t) { // noop } } }