Hi,--I am using netty 4.0.25Final to write a netty HTTP server. Apart from http codecs, I have three "sharable" handlers say handler1, handler2 and handler 3. I am modifying netty pipeline when the server gets a http request based on a condition. My pipeline looks like:pipeline.addLast(new HttpRequestDecoder(4096, 8192, 8192, false),new HttpResponseEncoder(),new HttpObjectAggregator(1048576),handler1);pipeline.addLast("handler2", ExceptionHandler.getInstance());In channelRead0 of handler1, based on a condition I add handler3 like:ctx.pipeline().addBefore("handler2", "handler3", Handler3.getInstance());I am trying to make 10 calls to my server with keep-alive= true using the following commandweighttp -c 1 -n 10 -k "http://localhost:8080/abc"Some of the request gives the below exception:[ERROR] 27 Feb 2015 12:33:52,370 (com.server.netty.Pipeline.ExceptionHandler:exceptionCaught:49)java.lang.IllegalArgumentException: Duplicate handler name: CheckTrafficHandlerat io.netty.channel.DefaultChannelPipeline.checkDuplicateName(DefaultChannelPipeline.java:959)at io.netty.channel.DefaultChannelPipeline.addBefore(DefaultChannelPipeline.java:159)at io.netty.channel.DefaultChannelPipeline.addBefore(DefaultChannelPipeline.java:151)at com.vdopia.rtb.netty.Pipeline.Handler1.channelRead0(RequestDecoder.java:156)at com.vdopia.rtb.netty.Pipeline. Handler1.channelRead0(RequestDecoder.java:98)at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:182)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)at java.lang.Thread.run(Thread.java:745)The exception goes off if I do any of the following:1. I remove keep-alive while making a call to the server2. Dont use dynamic pipeline.Has anybody encountered this error? It seems as if same pipeline is being used across some http requests. Please help me to resolve this issue.Thanks & Regards,Tanima
You received this message because you are subscribed to the Google Groups "Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netty+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netty/b0160563-60c8-430d-8d94-8cf1361097a6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof FullHttpRequest) {
FullHttpRequest req = (FullHttpRequest)msg;
// Fully asynchronous does
not block
doAsyncOperation().onSuccess(new Function() {
public void String call(String response) {
ctx.fireChannelRead(response);
}
});
}
}
I now understand that same pipeline is used if several requests are sent on the same connection. I have some more doubts regarding this. Below is how my netty pipeline looks likeBased on various parameters in the HTTP GET requests , various handlers are added in the pipeline. Asynchronous handler performs the asynchronous operation and frees up the NIO EventLoop thread. As the result is received in callback thread, it calls fireChannelRead on ChannelHandlerContext.
@Override
publicvoid channelRead(ChannelHandlerContext ctx,Object msg)throwsException{
if(msg instanceofFullHttpRequest){
FullHttpRequest req =(FullHttpRequest)msg;
// Fully asynchronous does not block
doAsyncOperation().onSuccess(newFunction(){
publicvoidString call(String response){
ctx.fireChannelRead(response);
}
});
}
}
1. Is the approach to handle asynchronous operation in this way correct? Is it ok to hold on the ctx object? I assume that the implementation of ChannelHandlerContext dispatch the write to an executor service so it is not run on the same thread as the callback.
2. Assuming the above implementation is correct - Suppose first http call goes through business logic handler1 - >AsyncHandler1 (it fires the db call and frees up NIOEventLoop thread). Before the the async operation completes, the second request comes on the same connection(channel), and now the parameters are such that it has to modify the pipeline and goes to business logic handler2. Now when the async operation completes and it fires channel read, the pipeline would have already been modified and it will go to the wrong handler. How can I solve this problem?
3. I looked at the PortUnification example. It also adds the channel handlers dynamically based on some conditions. The difference between the example and my scenario is my all handlers are shareable. Does this make any difference or the example will also have the same problem? Also, this example does
pipeline.remove(this);// this is PortUnificationServerHandler which is the decisionHandlerCan somebody tell me why this is done? Is this required?4. Is there a way in which pipeline is not reused even if multiple requests come on the same connection(channel) ?