/** Quick and dirty way to close a connection to a tablet server, if it wasn't already closed. */ @VisibleForTesting void disconnect() { Channel chancopy = chan; if (chancopy != null && chancopy.isConnected()) { Channels.disconnect(chancopy); } }
protected void sendRequest( HttpRequest request, SendRequestResultListener listener, HttpResponseProcessor responseProcessor) { if (isClosingOrClosed()) { listener.onSendRequestFailure(request, new ClosedChannelException()); } else if (!isConnected()) { listener.onSendRequestFailure(request, new RuntimeException("unable to send request")); } else { try { setResponseProcessor(responseProcessor, listener); } catch (DatabusException e) { listener.onSendRequestFailure(request, e.getCause()); _channel.close(); return; } // Send the HTTP request. if (_channel.isConnected()) { // ChannelFuture future = _channel.write(request); // future.addListener(new MySendRequestListener(request, listener)); _channel.write(request); } else { _log.error("disconnect on request: " + request.getUri()); listener.onSendRequestFailure(request, new ClosedChannelException()); } } }
/** * Forcefully shuts down the connection to this tablet server and fails all the outstanding RPCs. * Only use when shutting down a client. * * @return deferred object to use to track the shutting down of this connection */ public Deferred<Void> shutdown() { // First, check whether we have RPCs in flight and cancel them. for (Iterator<KuduRpc<?>> ite = rpcs_inflight.values().iterator(); ite.hasNext(); ) { KuduRpc<?> rpc = ite.next(); rpc.errback(new ConnectionResetException(null)); ite.remove(); } // Same for the pending RPCs. synchronized (this) { if (pending_rpcs != null) { for (Iterator<KuduRpc<?>> ite = pending_rpcs.iterator(); ite.hasNext(); ) { ite.next().errback(new ConnectionResetException(null)); ite.remove(); } } } final Channel chancopy = chan; if (chancopy == null) { return Deferred.fromResult(null); } if (chancopy.isConnected()) { Channels.disconnect(chancopy); // ... this is going to set it to null. // At this point, all in-flight RPCs are going to be failed. } if (chancopy.isBound()) { Channels.unbind(chancopy); } // It's OK to call close() on a Channel if it's already closed. final ChannelFuture future = Channels.close(chancopy); // Now wrap the ChannelFuture in a Deferred. final Deferred<Void> d = new Deferred<Void>(); // Opportunistically check if it's already completed successfully. if (future.isSuccess()) { d.callback(null); } else { // If we get here, either the future failed (yeah, that sounds weird) // or the future hasn't completed yet (heh). future.addListener( new ChannelFutureListener() { public void operationComplete(final ChannelFuture future) { if (future.isSuccess()) { d.callback(null); return; } final Throwable t = future.getCause(); if (t instanceof Exception) { d.callback(t); } else { // Wrap the Throwable because Deferred doesn't handle Throwables, // it only uses Exception. d.callback( new NonRecoverableException("Failed to shutdown: " + TabletClient.this, t)); } } }); } return d; }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel ch = e.getChannel(); Throwable cause = e.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, HttpResponseStatus.BAD_REQUEST); return; } if (cause != null) { if (cause.getClass().equals(IOException.class)) { LOGGER.debug("Connection error: " + cause); StartStopListenerDelegate startStopListenerDelegate = (StartStopListenerDelegate) ctx.getAttachment(); if (startStopListenerDelegate != null) { LOGGER.debug("Premature end, stopping..."); startStopListenerDelegate.stop(); } } else if (!cause.getClass().equals(ClosedChannelException.class)) { LOGGER.debug("Caught exception: " + cause); } } if (ch.isConnected()) { sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR); } e.getChannel().close(); }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { getLogger(ctx.getChannel()).debug("Error while processing imap request", e.getCause()); if (e.getCause() instanceof TooLongFrameException) { // Max line length exceeded // See RFC 2683 section 3.2.1 // // "For its part, a server should allow for a command line of at // least // 8000 octets. This provides plenty of leeway for accepting // reasonable // length commands from clients. The server should send a BAD // response // to a command that does not end within the server's maximum // accepted // command length." // // See also JAMES-1190 ImapResponseComposer composer = (ImapResponseComposer) ctx.getAttachment(); composer.untaggedResponse( ImapConstants.BAD + " failed. Maximum command line length exceeded"); } else { // logout on error not sure if that is the best way to handle it final ImapSession imapSession = (ImapSession) attributes.get(ctx.getChannel()); if (imapSession != null) imapSession.logout(); // Make sure we close the channel after all the buffers were flushed out Channel channel = ctx.getChannel(); if (channel.isConnected()) { channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } }
public void ping() { if (!channel.isConnected()) { System.err.println("MQtt Channel disconnected"); timer.cancel(); reconnect(); } channel.write(new PingReqMessage()); }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel ch = e.getChannel(); Throwable cause = e.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, BAD_REQUEST); return; } cause.printStackTrace(); if (ch.isConnected()) { sendError(ctx, INTERNAL_SERVER_ERROR); } }
/** * Send a file (with zero-copy) to the client. This method doesn't provide any security guarantee. * The caller is responsible for the argument they pass in. * * @param status The status of the request (e.g. 200 OK or 404 Not Found). * @param path The path to the file to send to the client. * @param max_age The expiration time of this entity, in seconds. This is not a timestamp, it's * how old the resource is allowed to be in the client cache. See RFC 2616 section 14.9 for * more information. Use 0 to disable caching. */ public void sendFile(final HttpResponseStatus status, final String path, final int max_age) throws IOException { if (max_age < 0) { throw new IllegalArgumentException("Negative max_age=" + max_age + " for path=" + path); } if (!chan.isConnected()) { done(); return; } RandomAccessFile file; try { file = new RandomAccessFile(path, "r"); } catch (FileNotFoundException e) { logWarn("File not found: " + e.getMessage()); if (querystring != null) { querystring.remove("png"); // Avoid potential recursion. } notFound(); return; } final long length = file.length(); { final DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); final String mimetype = guessMimeTypeFromUri(path); response.setHeader( HttpHeaders.Names.CONTENT_TYPE, mimetype == null ? "text/plain" : mimetype); final long mtime = new File(path).lastModified(); if (mtime > 0) { response.setHeader(HttpHeaders.Names.AGE, (System.currentTimeMillis() - mtime) / 1000); } else { logWarn("Found a file with mtime=" + mtime + ": " + path); } response.setHeader( HttpHeaders.Names.CACHE_CONTROL, max_age == 0 ? "no-cache" : "max-age=" + max_age); HttpHeaders.setContentLength(response, length); chan.write(response); } final DefaultFileRegion region = new DefaultFileRegion(file.getChannel(), 0, length); final ChannelFuture future = chan.write(region); future.addListener( new ChannelFutureListener() { public void operationComplete(final ChannelFuture future) { region.releaseExternalResources(); done(); } }); if (!HttpHeaders.isKeepAlive(request)) { future.addListener(ChannelFutureListener.CLOSE); } }
/** {@inheritDoc} */ public Channel poll(String uri) { if (!provider.getConfig().isSslConnectionPoolEnabled() && uri.startsWith("https")) { return null; } Channel channel = null; ConcurrentLinkedQueue<Channel> pooledConnectionForHost = connectionsPool.get(uri); if (pooledConnectionForHost != null) { boolean poolEmpty = false; while (!poolEmpty && channel == null) { if (pooledConnectionForHost.size() > 0) { channel = pooledConnectionForHost.poll(); } if (channel == null) { poolEmpty = true; } else if (!channel.isConnected() || !channel.isOpen()) { removeAll(channel); channel = null; } else { Timeout idleFuture = trackedIdleConnections.remove(channel); if (idleFuture != null) { idleFuture.cancel(); } // Double checking the channel hasn't been closed in between. if (!channel.isConnected() || !channel.isOpen()) { channel = null; } log.debug( "ConnectionsPool decrementAndGet totalConnections {}", trackedIdleConnections.size()); } } } return channel; }
/** Closes the connection. Note: this method will block until the connection is actually closed */ @Override public void close() { _log.info("closing connection to: " + _server.getAddress()); final State newState = switchToClosing(); if (State.CLOSING != newState && State.CLOSED != newState) { return; } if (null == _channel || !_channel.isConnected()) { switchToClosed(); } else { _channel.close(); awaitForCloseUninterruptibly(); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel ch = e.getChannel(); Throwable cause = e.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, BAD_REQUEST); return; } LOG.error("Shuffle error: ", cause); shuffleMetrics.failedOutput(); if (ch.isConnected()) { LOG.error("Shuffle error " + e); sendError(ctx, INTERNAL_SERVER_ERROR); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel ch = e.getChannel(); Throwable cause = e.getCause(); if (cause instanceof TooLongFrameException) { sendError(ctx, HttpResponseStatus.BAD_REQUEST); return; } if (cause != null && !cause.getClass().equals(ClosedChannelException.class) && !cause.getClass().equals(IOException.class)) { LOGGER.debug("Caught exception", cause); } if (ch.isConnected()) { sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR); } e.getChannel().close(); }
/** * Sends an HTTP reply to the client. * * @param status The status of the request (e.g. 200 OK or 404 Not Found). * @param buf The content of the reply to send. */ private void sendBuffer(final HttpResponseStatus status, final ChannelBuffer buf) { if (!chan.isConnected()) { done(); return; } final DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status); response.setHeader(HttpHeaders.Names.CONTENT_TYPE, guessMimeType(buf)); // TODO(tsuna): Server, X-Backend, etc. headers. response.setContent(buf); final boolean keepalive = HttpHeaders.isKeepAlive(request); if (keepalive) { HttpHeaders.setContentLength(response, buf.readableBytes()); } final ChannelFuture future = chan.write(response); if (!keepalive) { future.addListener(ChannelFutureListener.CLOSE); } done(); }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { ImapSession session = (ImapSession) attributes.get(ctx.getChannel()); ImapResponseComposer response = (ImapResponseComposer) ctx.getAttachment(); ImapMessage message = (ImapMessage) e.getMessage(); ChannelPipeline cp = ctx.getPipeline(); try { if (cp.get(NettyConstants.EXECUTION_HANDLER) != null) { cp.addBefore( NettyConstants.EXECUTION_HANDLER, NettyConstants.HEARTBEAT_HANDLER, heartbeatHandler); } else { cp.addBefore( NettyConstants.CORE_HANDLER, NettyConstants.HEARTBEAT_HANDLER, heartbeatHandler); } final ResponseEncoder responseEncoder = new ResponseEncoder(encoder, response, session); processor.process(message, responseEncoder, session); if (session.getState() == ImapSessionState.LOGOUT) { // Make sure we close the channel after all the buffers were flushed out Channel channel = ctx.getChannel(); if (channel.isConnected()) { channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } } final IOException failure = responseEncoder.getFailure(); if (failure != null) { final Logger logger = session.getLog(); logger.info(failure.getMessage()); if (logger.isDebugEnabled()) { logger.debug("Failed to write " + message, failure); } throw failure; } } finally { ctx.getPipeline().remove(NettyConstants.HEARTBEAT_HANDLER); } super.messageReceived(ctx, e); }
public boolean isConnected() { return channel.isConnected(); }
public boolean isConnected() { return channel != null && channel.isConnected() && channel.isOpen() && mailClientHandler.isLoggedIn(); }
@Override public final void sendMsg(List<OFMessage> msgs) { if (role == RoleState.MASTER && channel.isConnected()) { channel.write(msgs); } }
@Override public final void sendMsg(OFMessage m) { if (role == RoleState.MASTER && channel.isConnected()) { channel.write(Collections.singletonList(m)); } }
@Override public boolean isOpen() { return channel.isConnected(); }
@Override protected void dispose(Triplet<Channel, ChannelBuffer, ByteBuffer> resource) { Channel channel = resource.first(); if (channel.isConnected()) channel.close(); }
@Override public boolean isClosed() { return !channel.isConnected(); }
/** Closes the specified channel after all queued write requests are flushed. */ static void closeOnFlush(Channel ch) { if (ch.isConnected()) { ch.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } }
@Override public boolean isAvaliable() { return channel != null && channel.isConnected(); }