Search in sources :

Example 61 with ChannelFutureListener

use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.

the class ChunkedWriteHandler method doFlush.

private void doFlush(final ChannelHandlerContext ctx) {
    final Channel channel = ctx.channel();
    if (!channel.isActive()) {
        discard(null);
        return;
    }
    boolean requiresFlush = true;
    ByteBufAllocator allocator = ctx.alloc();
    while (channel.isWritable()) {
        final PendingWrite currentWrite = queue.peek();
        if (currentWrite == null) {
            break;
        }
        if (currentWrite.promise.isDone()) {
            // This might happen e.g. in the case when a write operation
            // failed, but there're still unconsumed chunks left.
            // Most chunked input sources would stop generating chunks
            // and report end of input, but this doesn't work with any
            // source wrapped in HttpChunkedInput.
            // Note, that we're not trying to release the message/chunks
            // as this had to be done already by someone who resolved the
            // promise (using ChunkedInput.close method).
            // See https://github.com/netty/netty/issues/8700.
            queue.remove();
            continue;
        }
        final Object pendingMessage = currentWrite.msg;
        if (pendingMessage instanceof ChunkedInput) {
            final ChunkedInput<?> chunks = (ChunkedInput<?>) pendingMessage;
            boolean endOfInput;
            boolean suspend;
            Object message = null;
            try {
                message = chunks.readChunk(allocator);
                endOfInput = chunks.isEndOfInput();
                if (message == null) {
                    // No need to suspend when reached at the end.
                    suspend = !endOfInput;
                } else {
                    suspend = false;
                }
            } catch (final Throwable t) {
                queue.remove();
                if (message != null) {
                    ReferenceCountUtil.release(message);
                }
                closeInput(chunks);
                currentWrite.fail(t);
                break;
            }
            if (suspend) {
                // more chunks arrive. Nothing to write or notify.
                break;
            }
            if (message == null) {
                // If message is null write an empty ByteBuf.
                // See https://github.com/netty/netty/issues/1671
                message = Unpooled.EMPTY_BUFFER;
            }
            if (endOfInput) {
                // We need to remove the element from the queue before we call writeAndFlush() as this operation
                // may cause an action that also touches the queue.
                queue.remove();
            }
            // Flush each chunk to conserve memory
            ChannelFuture f = ctx.writeAndFlush(message);
            if (endOfInput) {
                if (f.isDone()) {
                    handleEndOfInputFuture(f, currentWrite);
                } else {
                    // Register a listener which will close the input once the write is complete.
                    // This is needed because the Chunk may have some resource bound that can not
                    // be closed before its not written.
                    // 
                    // See https://github.com/netty/netty/issues/303
                    f.addListener(new ChannelFutureListener() {

                        @Override
                        public void operationComplete(ChannelFuture future) {
                            handleEndOfInputFuture(future, currentWrite);
                        }
                    });
                }
            } else {
                final boolean resume = !channel.isWritable();
                if (f.isDone()) {
                    handleFuture(f, currentWrite, resume);
                } else {
                    f.addListener(new ChannelFutureListener() {

                        @Override
                        public void operationComplete(ChannelFuture future) {
                            handleFuture(future, currentWrite, resume);
                        }
                    });
                }
            }
            requiresFlush = false;
        } else {
            queue.remove();
            ctx.write(pendingMessage, currentWrite.promise);
            requiresFlush = true;
        }
        if (!channel.isActive()) {
            discard(new ClosedChannelException());
            break;
        }
    }
    if (requiresFlush) {
        ctx.flush();
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ByteBufAllocator(io.netty.buffer.ByteBufAllocator) ClosedChannelException(java.nio.channels.ClosedChannelException) Channel(io.netty.channel.Channel) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Example 62 with ChannelFutureListener

use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2MultiplexTest method channelClosedWhenWriteFutureFails.

@Test
public void channelClosedWhenWriteFutureFails() {
    final Queue<ChannelPromise> writePromises = new ArrayDeque<ChannelPromise>();
    LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
    assertTrue(childChannel.isOpen());
    assertTrue(childChannel.isActive());
    final AtomicBoolean channelOpen = new AtomicBoolean(true);
    final AtomicBoolean channelActive = new AtomicBoolean(true);
    Http2Headers headers = new DefaultHttp2Headers();
    when(frameWriter.writeHeaders(eqCodecCtx(), anyInt(), eq(headers), anyInt(), anyBoolean(), any(ChannelPromise.class))).thenAnswer(new Answer<ChannelFuture>() {

        @Override
        public ChannelFuture answer(InvocationOnMock invocationOnMock) {
            ChannelPromise promise = invocationOnMock.getArgument(5);
            writePromises.offer(promise);
            return promise;
        }
    });
    ChannelFuture f = childChannel.writeAndFlush(new DefaultHttp2HeadersFrame(headers));
    assertFalse(f.isDone());
    f.addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            channelOpen.set(future.channel().isOpen());
            channelActive.set(future.channel().isActive());
        }
    });
    ChannelPromise first = writePromises.poll();
    first.setFailure(new ClosedChannelException());
    f.awaitUninterruptibly();
    assertFalse(channelOpen.get());
    assertFalse(channelActive.get());
    assertFalse(childChannel.isActive());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ClosedChannelException(java.nio.channels.ClosedChannelException) ChannelPromise(io.netty.channel.ChannelPromise) Http2TestUtil.anyChannelPromise(io.netty.handler.codec.http2.Http2TestUtil.anyChannelPromise) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ArrayDeque(java.util.ArrayDeque) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) ClosedChannelException(java.nio.channels.ClosedChannelException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.jupiter.api.Test)

Example 63 with ChannelFutureListener

use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2MultiplexTest method channelClosedWhenChannelClosePromiseCompletes.

@Test
public void channelClosedWhenChannelClosePromiseCompletes() {
    LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
    assertTrue(childChannel.isOpen());
    assertTrue(childChannel.isActive());
    final AtomicBoolean channelOpen = new AtomicBoolean(true);
    final AtomicBoolean channelActive = new AtomicBoolean(true);
    childChannel.closeFuture().addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) {
            channelOpen.set(future.channel().isOpen());
            channelActive.set(future.channel().isActive());
        }
    });
    childChannel.close().syncUninterruptibly();
    assertFalse(channelOpen.get());
    assertFalse(channelActive.get());
    assertFalse(childChannel.isActive());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Test(org.junit.jupiter.api.Test)

Example 64 with ChannelFutureListener

use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2MultiplexTransportTest method testFireChannelReadAfterHandshakeSuccess.

private void testFireChannelReadAfterHandshakeSuccess(SslProvider provider) throws Exception {
    SelfSignedCertificate ssc = null;
    try {
        ssc = new SelfSignedCertificate();
        final SslContext serverCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(eventLoopGroup);
        sb.channel(NioServerSocketChannel.class);
        sb.childHandler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(serverCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_1_1) {

                    @Override
                    protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
                        ctx.pipeline().addLast(new Http2FrameCodecBuilder(true).build());
                        ctx.pipeline().addLast(new Http2MultiplexHandler(new ChannelInboundHandlerAdapter() {

                            @Override
                            public void channelRead(final ChannelHandlerContext ctx, Object msg) {
                                if (msg instanceof Http2HeadersFrame && ((Http2HeadersFrame) msg).isEndStream()) {
                                    ctx.writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), false)).addListener(new ChannelFutureListener() {

                                        @Override
                                        public void operationComplete(ChannelFuture future) {
                                            ctx.writeAndFlush(new DefaultHttp2DataFrame(Unpooled.copiedBuffer("Hello World", CharsetUtil.US_ASCII), true));
                                        }
                                    });
                                }
                                ReferenceCountUtil.release(msg);
                            }
                        }));
                    }
                });
            }
        });
        serverChannel = sb.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
        final SslContext clientCtx = SslContextBuilder.forClient().sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(ApplicationProtocolConfig.Protocol.ALPN, ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
        final CountDownLatch latch = new CountDownLatch(1);
        Bootstrap bs = new Bootstrap();
        bs.group(eventLoopGroup);
        bs.channel(NioSocketChannel.class);
        bs.handler(new ChannelInitializer<Channel>() {

            @Override
            protected void initChannel(Channel ch) {
                ch.pipeline().addLast(clientCtx.newHandler(ch.alloc()));
                ch.pipeline().addLast(new Http2FrameCodecBuilder(false).build());
                ch.pipeline().addLast(new Http2MultiplexHandler(DISCARD_HANDLER));
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                    @Override
                    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
                        if (evt instanceof SslHandshakeCompletionEvent) {
                            SslHandshakeCompletionEvent handshakeCompletionEvent = (SslHandshakeCompletionEvent) evt;
                            if (handshakeCompletionEvent.isSuccess()) {
                                Http2StreamChannelBootstrap h2Bootstrap = new Http2StreamChannelBootstrap(clientChannel);
                                h2Bootstrap.handler(new ChannelInboundHandlerAdapter() {

                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) {
                                        if (msg instanceof Http2DataFrame && ((Http2DataFrame) msg).isEndStream()) {
                                            latch.countDown();
                                        }
                                        ReferenceCountUtil.release(msg);
                                    }
                                });
                                h2Bootstrap.open().addListener(new FutureListener<Channel>() {

                                    @Override
                                    public void operationComplete(Future<Channel> future) {
                                        if (future.isSuccess()) {
                                            future.getNow().writeAndFlush(new DefaultHttp2HeadersFrame(new DefaultHttp2Headers(), true));
                                        }
                                    }
                                });
                            }
                        }
                    }
                });
            }
        });
        clientChannel = bs.connect(serverChannel.localAddress()).sync().channel();
        latch.await();
    } finally {
        if (ssc != null) {
            ssc.delete();
        }
    }
}
Also used : SelfSignedCertificate(io.netty.handler.ssl.util.SelfSignedCertificate) SslHandshakeCompletionEvent(io.netty.handler.ssl.SslHandshakeCompletionEvent) InetSocketAddress(java.net.InetSocketAddress) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ApplicationProtocolConfig(io.netty.handler.ssl.ApplicationProtocolConfig) Bootstrap(io.netty.bootstrap.Bootstrap) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) SslContext(io.netty.handler.ssl.SslContext) ChannelFuture(io.netty.channel.ChannelFuture) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Example 65 with ChannelFutureListener

use of org.apache.flink.shaded.netty4.io.netty.channel.ChannelFutureListener in project netty by netty.

the class Http2TestUtil method newVoidPromise.

static ChannelPromise newVoidPromise(final Channel channel) {
    return new DefaultChannelPromise(channel, ImmediateEventExecutor.INSTANCE) {

        @Override
        public ChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener) {
            throw new AssertionFailedError();
        }

        @Override
        public ChannelPromise addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners) {
            throw new AssertionFailedError();
        }

        @Override
        public boolean isVoid() {
            return true;
        }

        @Override
        public boolean tryFailure(Throwable cause) {
            channel().pipeline().fireExceptionCaught(cause);
            return true;
        }

        @Override
        public ChannelPromise setFailure(Throwable cause) {
            tryFailure(cause);
            return this;
        }

        @Override
        public ChannelPromise unvoid() {
            ChannelPromise promise = new DefaultChannelPromise(channel, ImmediateEventExecutor.INSTANCE);
            promise.addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        channel().pipeline().fireExceptionCaught(future.cause());
                    }
                }
            });
            return promise;
        }
    };
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) ChannelPromise(io.netty.channel.ChannelPromise) DefaultChannelPromise(io.netty.channel.DefaultChannelPromise) AssertionFailedError(junit.framework.AssertionFailedError) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Aggregations

ChannelFutureListener (io.netty.channel.ChannelFutureListener)223 ChannelFuture (io.netty.channel.ChannelFuture)208 Channel (io.netty.channel.Channel)70 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)57 ByteBuf (io.netty.buffer.ByteBuf)49 Bootstrap (io.netty.bootstrap.Bootstrap)43 Test (org.junit.jupiter.api.Test)41 CountDownLatch (java.util.concurrent.CountDownLatch)36 IOException (java.io.IOException)35 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)33 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)31 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)31 InetSocketAddress (java.net.InetSocketAddress)27 ClosedChannelException (java.nio.channels.ClosedChannelException)25 ChannelPromise (io.netty.channel.ChannelPromise)21 Logger (org.slf4j.Logger)21 LoggerFactory (org.slf4j.LoggerFactory)21 NioEventLoopGroup (io.netty.channel.nio.NioEventLoopGroup)20 EventLoopGroup (io.netty.channel.EventLoopGroup)18 List (java.util.List)17