Ich versuche, eine durchflusskontrollierte Netty-Pipeline mit (unter anderem) ein FlowControlHandler in der Nähe der Oberfläche zu erstellen. Flow-kontrolliert in dem Sinne, dass es pro Anruf an read () mehrere Nachrichten ausgibt. Ich habe das Problem auf eine unerwartete Wechselwirkung zwischen FlowControlHandler und httpContentDeCompressor isoliert, die im folgenden Test in der Netty-Test-Suite reproduziert werden:
Code: Select all
index d9f5cd5b8d..f8edf63a29 100644
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentDecompressorTest.java
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpContentDecompressorTest.java
@@ -20,6 +20,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.embedded.EmbeddedChannel;
+import io.netty.handler.flow.FlowControlHandler;
import org.junit.jupiter.api.Test;
import java.util.concurrent.atomic.AtomicInteger;
@@ -70,4 +71,33 @@ public class HttpContentDecompressorTest {
assertEquals(2, readCalled.get());
assertFalse(channel.finishAndReleaseAll());
}
+
+ @Test
+ public void testFlowController() {
+ final AtomicInteger messagesEmitted = new AtomicInteger();
+ final EmbeddedChannel channel = new EmbeddedChannel(
+ new FlowControlHandler(),
+ new HttpContentDecompressor(),
+ new ChannelInboundHandlerAdapter() {
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) {
+ messagesEmitted.incrementAndGet();
+ }
+ });
+
+ channel.config().setAutoRead(false);
+
+ final HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
+ response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
+
+ assertFalse(channel.writeInbound(response));
+ assertFalse(channel.writeInbound(new DefaultHttpContent(Unpooled.buffer(1))));
+ assertFalse(channel.writeInbound(new DefaultHttpContent(Unpooled.buffer(1))));
+
+ assertEquals(1, messagesEmitted.get());
+ channel.read();
+ assertEquals(2, messagesEmitted.get());
+ channel.read();
+ assertEquals(3, messagesEmitted.get());
+ }
}
Code: Select all
org.opentest4j.AssertionFailedError:
Expected :1
Actual :3
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:145)
at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:527)
at io.netty.handler.codec.http.HttpContentDecompressorTest.testFlowController(HttpContentDecompressorTest.java:97)
...