@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { super.write(ctx, msg, promise); // Close the connection immediately after LastContent is written, rather than // waiting until the graceful-delay is up if this flag is set. if (isEndOfRequestResponse(msg)) { if (HttpChannelFlags.CLOSE_AFTER_RESPONSE.get(ctx)) { promise.addListener(future -> { Channel parent = parentChannel(ctx); closeChannel(ctx, parent, ConnectionCloseType.fromChannel(ctx.channel()), ctx.newPromise()); }); } } }
protected void gracefully(Channel channel, ChannelPromise promise) { if (isAlreadyClosing(channel)) { promise.setSuccess(); return; } gracefulConnectionShutdown(channel); promise.setSuccess(); }
protected void closeChannel(ChannelHandlerContext ctx, Channel channel, ConnectionCloseType evt, ChannelPromise promise) { switch (evt) { case DELAYED_GRACEFUL: gracefullyWithDelay(ctx, channel, promise); break; case GRACEFUL: gracefully(channel, promise); break; case IMMEDIATE: immediately(channel, promise); break; default: throw new IllegalArgumentException("Unknown ConnectionCloseEvent type! - " + String.valueOf(evt)); } }
@Override public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { // Close according to the specified close type. Channel parent = parentChannel(ctx); ConnectionCloseType type = ConnectionCloseType.fromChannel(parent); closeChannel(ctx, parent, type, promise); // Don't pass this event further down the pipeline. }
gracefully(channel, promise); return; if (isAlreadyClosing(channel)) { promise.setSuccess(); return; gracefulConnectionShutdown(channel); promise.setSuccess();
protected void immediately(Channel parent, ChannelPromise promise) { if (isAlreadyClosing(parent)) { promise.setSuccess(); return; } if (parent.isActive()) { parent.close(promise); } else { promise.setSuccess(); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof Http2Exception) { Http2Exception h2e = (Http2Exception) cause; if (h2e.error() == Http2Error.NO_ERROR && Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN.equals(h2e.shutdownHint())) { // This is the exception we threw ourselves to make the http2 codec gracefully close the connection. So just // swallow it so that it doesn't propagate and get logged. } else { super.exceptionCaught(ctx, cause); } } else if (cause instanceof Errors.NativeIoException) { LOG.debug("SwallowHttp2ExceptionShutdownHint, NativeIoException " + cause); Http2ConnectionCloseHandler.incrementExceptionCounter(cause); } else { LOG.debug("SwallowHttp2ExceptionShutdownHint unknown exception " + cause); if (!SWALLOW_UNKNOWN_EXCEPTIONS_ON_CONN_CLOSE.get()) { super.exceptionCaught(ctx, cause); } } } }
Http2ConnectionCloseHandler connectionCloseHandler = new Http2ConnectionCloseHandler(channelConfig.get(CommonChannelConfigKeys.connCloseDelay), registry); Http2ConnectionExpiryHandler connectionExpiryHandler = new Http2ConnectionExpiryHandler(maxRequestsPerConnection, maxRequestsPerConnectionInBrownout, connectionExpiry);
gracefully(channel, promise); return; if (isAlreadyClosing(channel)) { promise.setSuccess(); return; gracefulConnectionShutdown(channel); promise.setSuccess();
@Override public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { // Close according to the specified close type. Channel parent = parentChannel(ctx); ConnectionCloseType type = ConnectionCloseType.fromChannel(parent); closeChannel(ctx, parent, type, promise); // Don't pass this event further down the pipeline. }
protected void immediately(Channel parent, ChannelPromise promise) { if (isAlreadyClosing(parent)) { promise.setSuccess(); return; } if (parent.isActive()) { parent.close(promise); } else { promise.setSuccess(); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof Http2Exception) { Http2Exception h2e = (Http2Exception) cause; if (h2e.error() == Http2Error.NO_ERROR && Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN.equals(h2e.shutdownHint())) { // This is the exception we threw ourselves to make the http2 codec gracefully close the connection. So just // swallow it so that it doesn't propagate and get logged. } else { super.exceptionCaught(ctx, cause); } } else if (cause instanceof Errors.NativeIoException) { LOG.debug("SwallowHttp2ExceptionShutdownHint, NativeIoException " + cause); Http2ConnectionCloseHandler.incrementExceptionCounter(cause); } else { LOG.debug("SwallowHttp2ExceptionShutdownHint unknown exception " + cause); if (!SWALLOW_UNKNOWN_EXCEPTIONS_ON_CONN_CLOSE.get()) { super.exceptionCaught(ctx, cause); } } } }
Http2ConnectionCloseHandler connectionCloseHandler = new Http2ConnectionCloseHandler(channelConfig.get(CommonChannelConfigKeys.connCloseDelay), registry); Http2ConnectionExpiryHandler connectionExpiryHandler = new Http2ConnectionExpiryHandler(maxRequestsPerConnection, maxRequestsPerConnectionInBrownout, connectionExpiry);
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { super.write(ctx, msg, promise); // Close the connection immediately after LastContent is written, rather than // waiting until the graceful-delay is up if this flag is set. if (isEndOfRequestResponse(msg)) { if (HttpChannelFlags.CLOSE_AFTER_RESPONSE.get(ctx)) { promise.addListener(future -> { Channel parent = parentChannel(ctx); closeChannel(ctx, parent, ConnectionCloseType.fromChannel(ctx.channel()), ctx.newPromise()); }); } } }
protected void closeChannel(ChannelHandlerContext ctx, Channel channel, ConnectionCloseType evt, ChannelPromise promise) { switch (evt) { case DELAYED_GRACEFUL: gracefullyWithDelay(ctx, channel, promise); break; case GRACEFUL: gracefully(channel, promise); break; case IMMEDIATE: immediately(channel, promise); break; default: throw new IllegalArgumentException("Unknown ConnectionCloseEvent type! - " + String.valueOf(evt)); } }
gracefully(channel, promise); return; if (isAlreadyClosing(channel)) { promise.setSuccess(); return; gracefulConnectionShutdown(channel); promise.setSuccess();
@Override public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { // Close according to the specified close type. Channel parent = parentChannel(ctx); ConnectionCloseType type = ConnectionCloseType.fromChannel(parent); closeChannel(ctx, parent, type, promise); // Don't pass this event further down the pipeline. }
protected void gracefully(Channel channel, ChannelPromise promise) { if (isAlreadyClosing(channel)) { promise.setSuccess(); return; } gracefulConnectionShutdown(channel); promise.setSuccess(); }
protected void immediately(Channel parent, ChannelPromise promise) { if (isAlreadyClosing(parent)) { promise.setSuccess(); return; } if (parent.isActive()) { parent.close(promise); } else { promise.setSuccess(); } }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof Http2Exception) { Http2Exception h2e = (Http2Exception) cause; if (h2e.error() == Http2Error.NO_ERROR && Http2Exception.ShutdownHint.GRACEFUL_SHUTDOWN.equals(h2e.shutdownHint())) { // This is the exception we threw ourselves to make the http2 codec gracefully close the connection. So just // swallow it so that it doesn't propagate and get logged. } else { super.exceptionCaught(ctx, cause); } } else if (cause instanceof Errors.NativeIoException) { LOG.debug("SwallowHttp2ExceptionShutdownHint, NativeIoException " + cause); Http2ConnectionCloseHandler.incrementExceptionCounter(cause); } else { LOG.debug("SwallowHttp2ExceptionShutdownHint unknown exception " + cause); if (!SWALLOW_UNKNOWN_EXCEPTIONS_ON_CONN_CLOSE.get()) { super.exceptionCaught(ctx, cause); } } } }