Search in sources :

Example 21 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopAutoRead.

@Test
public void childQueueIsDrainedAndNewDataIsDispatchedInParentReadLoopAutoRead() {
    AtomicInteger numReads = new AtomicInteger(1);
    final AtomicInteger channelReadCompleteCount = new AtomicInteger(0);
    final AtomicBoolean shouldDisableAutoRead = new AtomicBoolean();
    Consumer<ChannelHandlerContext> ctxConsumer = new Consumer<ChannelHandlerContext>() {

        @Override
        public void accept(ChannelHandlerContext obj) {
            channelReadCompleteCount.incrementAndGet();
            if (shouldDisableAutoRead.get()) {
                obj.channel().config().setAutoRead(false);
            }
        }
    };
    LastInboundHandler inboundHandler = new LastInboundHandler(ctxConsumer);
    Http2StreamChannel childChannel = newInboundStream(3, false, numReads, inboundHandler);
    childChannel.config().setAutoRead(false);
    Http2DataFrame dataFrame1 = new DefaultHttp2DataFrame(bb("1")).stream(childChannel.stream());
    Http2DataFrame dataFrame2 = new DefaultHttp2DataFrame(bb("2")).stream(childChannel.stream());
    Http2DataFrame dataFrame3 = new DefaultHttp2DataFrame(bb("3")).stream(childChannel.stream());
    Http2DataFrame dataFrame4 = new DefaultHttp2DataFrame(bb("4")).stream(childChannel.stream());
    assertEquals(new DefaultHttp2HeadersFrame(request).stream(childChannel.stream()), inboundHandler.readInbound());
    ChannelHandler readCompleteSupressHandler = new ChannelInboundHandlerAdapter() {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
        // We want to simulate the parent channel calling channelRead and delay calling channelReadComplete.
        }
    };
    parentChannel.pipeline().addFirst(readCompleteSupressHandler);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("1"), 0, false);
    assertEqualsAndRelease(dataFrame1, inboundHandler.<Http2DataFrame>readInbound());
    // We want one item to be in the queue, and allow the numReads to be larger than 1. This will ensure that
    // when beginRead() is called the child channel is added to the readPending queue of the parent channel.
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("2"), 0, false);
    numReads.set(10);
    shouldDisableAutoRead.set(true);
    childChannel.config().setAutoRead(true);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("3"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("4"), 0, false);
    // Detecting EOS should flush all pending data regardless of read calls.
    assertEqualsAndRelease(dataFrame2, inboundHandler.<Http2DataFrame>readInbound());
    assertEqualsAndRelease(dataFrame3, inboundHandler.<Http2DataFrame>readInbound());
    assertEqualsAndRelease(dataFrame4, inboundHandler.<Http2DataFrame>readInbound());
    assertNull(inboundHandler.readInbound());
    // Now we want to call channelReadComplete and simulate the end of the read loop.
    parentChannel.pipeline().remove(readCompleteSupressHandler);
    parentChannel.flushInbound();
    // 3 = 1 for initialization + 1 for read when auto read was off + 1 for when auto read was back on
    assertEquals(3, channelReadCompleteCount.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Consumer(io.netty.handler.codec.http2.LastInboundHandler.Consumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelHandler(io.netty.channel.ChannelHandler) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) Test(org.junit.jupiter.api.Test)

Example 22 with Http2StreamChannel

use of io.netty.handler.codec.http2.Http2StreamChannel in project netty by netty.

the class Http2MultiplexTest method useReadWithoutAutoReadBuffered.

private void useReadWithoutAutoReadBuffered(final boolean triggerOnReadComplete) {
    LastInboundHandler inboundHandler = new LastInboundHandler();
    Http2StreamChannel childChannel = newInboundStream(3, false, inboundHandler);
    assertTrue(childChannel.config().isAutoRead());
    childChannel.config().setAutoRead(false);
    assertFalse(childChannel.config().isAutoRead());
    Http2HeadersFrame headersFrame = inboundHandler.readInbound();
    assertNotNull(headersFrame);
    // Write some bytes to get the channel into the idle state with buffered data and also verify we
    // do not dispatch it until we receive a read() call.
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("hello world"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("foo"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar"), 0, false);
    // Add a handler which will request reads.
    childChannel.pipeline().addFirst(new ChannelInboundHandlerAdapter() {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            super.channelReadComplete(ctx);
            if (triggerOnReadComplete) {
                ctx.read();
                ctx.read();
            }
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ctx.fireChannelRead(msg);
            if (!triggerOnReadComplete) {
                ctx.read();
                ctx.read();
            }
        }
    });
    inboundHandler.channel().read();
    verifyFramesMultiplexedToCorrectChannel(childChannel, inboundHandler, 3);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("hello world2"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("foo2"), 0, false);
    frameInboundWriter.writeInboundData(childChannel.stream().id(), bb("bar2"), 0, true);
    verifyFramesMultiplexedToCorrectChannel(childChannel, inboundHandler, 3);
}
Also used : ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) StreamException(io.netty.handler.codec.http2.Http2Exception.StreamException) ClosedChannelException(java.nio.channels.ClosedChannelException) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter)

Aggregations

Test (org.junit.jupiter.api.Test)14 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)9 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)9 StreamException (io.netty.handler.codec.http2.Http2Exception.StreamException)9 ChannelPromise (io.netty.channel.ChannelPromise)7 Http2TestUtil.anyChannelPromise (io.netty.handler.codec.http2.Http2TestUtil.anyChannelPromise)7 ClosedChannelException (java.nio.channels.ClosedChannelException)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6 Channel (io.netty.channel.Channel)5 ChannelFuture (io.netty.channel.ChannelFuture)5 Http2StreamChannel (io.netty.handler.codec.http2.Http2StreamChannel)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 InvocationOnMock (org.mockito.invocation.InvocationOnMock)4 ChannelHandler (io.netty.channel.ChannelHandler)3 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)3 Http2StreamChannelBootstrap (io.netty.handler.codec.http2.Http2StreamChannelBootstrap)3 Consumer (io.netty.handler.codec.http2.LastInboundHandler.Consumer)3 ArrayList (java.util.ArrayList)3 MetricRegistry (com.codahale.metrics.MetricRegistry)2 MultiplexedChannelRecordTest (com.github.ambry.network.http2.MultiplexedChannelRecordTest)2