I&#39;ve been trying to write a simple HTTP-based RPC server using Netty 3.2.1. I basically took the Snoop example server and deleted code from it :-)<div><br></div><div>I profiled my application and found that a lot of time was being spent in HttpRequestDecoder.decode. More specifically, it seems to be spinning on ReplayingDecoderBuffer.readUnsignedByte (and its callee checkReadableBytes). Has anyone run into this before?</div>
<div><br></div><div>This is my pipeline:</div><div><br></div><div>ChannelPipeline pipeline = pipeline();</div><div><div>pipeline.addLast(&quot;decoder&quot;, new HttpRequestDecoder());</div><div>pipeline.addLast(&quot;aggregator&quot;, new HttpChunkAggregator(1048576));</div>
<div>pipeline.addLast(&quot;encoder&quot;, new HttpResponseEncoder());</div><div>pipeline.addLast(&quot;deflater&quot;, new HttpContentCompressor());</div><div>HTTPRequestHandler handler = new HTTPRequestHandler();</div><div>
handler.setBridge(bridge);</div><div>pipeline.addLast(&quot;handler&quot;, handler);</div></div><div><br></div><div>And this is the relevant part of my handler:</div><div><br></div><div><div>public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throws Exception {</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>HttpRequest request = (HttpRequest) event.getMessage();</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>ChannelBuffer content = request.getContent();</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>String contentString = content.toString(CharsetUtil.UTF_8);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>String rpcResponse = bridge.performRPC(contentString);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// Decide whether to close the connection or not.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>boolean keepAlive = isKeepAlive(request);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// Build the response object.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>response.setContent(ChannelBuffers.copiedBuffer(rpcResponse, CharsetUtil.UTF_8));</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>response.setHeader(CONTENT_TYPE, &quot;text/plain; charset=UTF-8&quot;);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if (keepAlive) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// Add &#39;Content-Length&#39; header only for a keep-alive connection.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>
<br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// Write the response.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>ChannelFuture future = event.getChannel().write(response);</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// Close the non-keep-alive connection after the write operation is done.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if (!keepAlive) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>future.addListener(ChannelFutureListener.CLOSE);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div></div><div><br>
</div><div>The expensive code path goes through future.addListener(); I&#39;ve attached a clumsy pair of screenshots from my profiler (YourKit 8.x).</div><div><br></div><div>Thanks very much for your time.</div>