From 8a2f1bd87ad426f3ea683753b2fc9d641d4d35b9 Mon Sep 17 00:00:00 2001 From: Francesco Nigro Date: Wed, 22 Feb 2023 17:57:09 +0100 Subject: [PATCH] Save expensive slow path type checks (#7942) --- frameworks/Java/netty/netty.dockerfile | 2 +- frameworks/Java/netty/pom.xml | 5 +-- .../main/java/hello/HelloServerHandler.java | 16 ++++++++++ .../java/hello/HelloServerInitializer.java | 32 +++++++++++++++++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/frameworks/Java/netty/netty.dockerfile b/frameworks/Java/netty/netty.dockerfile index 5c4d1353d6e2..751286961f72 100644 --- a/frameworks/Java/netty/netty.dockerfile +++ b/frameworks/Java/netty/netty.dockerfile @@ -10,4 +10,4 @@ COPY --from=maven /netty/target/netty-example-0.1-jar-with-dependencies.jar app. EXPOSE 8080 -CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-jar", "app.jar"] +CMD ["java", "-server", "-XX:+UseNUMA", "-XX:+UseParallelGC", "-XX:+AggressiveOpts", "-Dio.netty.buffer.checkBounds=false", "-Dio.netty.buffer.checkAccessible=false", "-jar", "app.jar"] \ No newline at end of file diff --git a/frameworks/Java/netty/pom.xml b/frameworks/Java/netty/pom.xml index fa323e6cefb0..23ec0a5b3ab1 100644 --- a/frameworks/Java/netty/pom.xml +++ b/frameworks/Java/netty/pom.xml @@ -11,7 +11,8 @@ 11 11 - 4.1.86.Final + 4.1.89.Final + 0.0.18.Final jar @@ -41,7 +42,7 @@ io.netty.incubator netty-incubator-transport-native-io_uring - 0.0.15.Final + ${io_uring.version} linux-x86_64 diff --git a/frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java b/frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java index 75f05a40c495..c82e008c4d6b 100644 --- a/frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java +++ b/frameworks/Java/netty/src/main/java/hello/HelloServerHandler.java @@ -28,8 +28,10 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.LastHttpContent; import io.netty.util.AsciiString; import io.netty.util.CharsetUtil; import io.netty.util.ReferenceCountUtil; @@ -88,6 +90,20 @@ public void run() { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + // fast path + if (msg == LastHttpContent.EMPTY_LAST_CONTENT) { + return; + } + if (msg.getClass() == DefaultHttpRequest.class) { + DefaultHttpRequest request = (DefaultHttpRequest) msg; + process(ctx, request); + } else { + channelReadSlowPath(ctx, msg); + } + } + + private void channelReadSlowPath(ChannelHandlerContext ctx, Object msg) throws Exception { + // slow path if (msg instanceof HttpRequest) { try { HttpRequest request = (HttpRequest) msg; diff --git a/frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java b/frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java index 0c4209e12822..060dd49930c4 100644 --- a/frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java +++ b/frameworks/Java/netty/src/main/java/hello/HelloServerInitializer.java @@ -4,12 +4,17 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.DefaultHttpRequest; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; +import io.netty.handler.codec.http.HttpVersion; public class HelloServerInitializer extends ChannelInitializer { - private ScheduledExecutorService service; + private final ScheduledExecutorService service; public HelloServerInitializer(ScheduledExecutorService service) { this.service = service; @@ -18,8 +23,29 @@ public HelloServerInitializer(ScheduledExecutorService service) { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline() - .addLast("encoder", new HttpResponseEncoder()) - .addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false)) + .addLast("encoder", new HttpResponseEncoder() { + @Override + public boolean acceptOutboundMessage(final Object msg) throws Exception { + if (msg.getClass() == DefaultFullHttpResponse.class) { + return true; + } + return super.acceptOutboundMessage(msg); + } + }) + .addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false) { + + @Override + protected HttpMessage createMessage(final String[] initialLine) throws Exception { + return new DefaultHttpRequest( + HttpVersion.valueOf(initialLine[2]), + HttpMethod.valueOf(initialLine[0]), initialLine[1], validateHeaders); + } + + @Override + protected boolean isContentAlwaysEmpty(final HttpMessage msg) { + return false; + } + }) .addLast("handler", new HelloServerHandler(service)); } }