Handling Exceptions when Closing

"이희승 (Trustin Lee)" trustin at gmail.com
Mon Jun 20 12:15:42 EDT 2011


Hi Frank,

What do you exactly do in your real world applications' closeRequested() 
handler method, and why is it triggering an exception?

Francis Barber wrote:
> Hello,
>
> I have a question regarding handling exceptions that thrown by a
> ChannelHandler when handling a close event.  Rather than trying to
> explain, I've included a contrived example below to illustrate the point.
>
> The problem is that this code goes off into an infinite loop until
> eventually we run out of stack.  If an exception is thrown while the
> close event is going downstream, an exception event is sent back
> upstream.  There are two problems here.
> (a) The channel actually doesn't get closed because the event doesn't
> reach the sink.  While this isn't necessarily wrong, the ChannelFuture
> doesn't get told about the exception so it is never "done".
> (b) I would be able to set failure on the ChannelFuture myself in my
> upstream exception handler, but the original event (the close event) is
> lost in AbstractChannelSink.exceptionCaught().  This makes it impossible
> for my exception handler to tell that the channel was in the process of
> being closed, so naturally it decides to close the channel again, and
> around we go.
>
> Is this a bug, or is there a different way I'm meant to handle exceptions?
>
> Many thanks,
> Frank.
>
>
> import org.jboss.netty.bootstrap.*;
> import org.jboss.netty.channel.*;
> import org.junit.Test;
>
> public class Experiment {
>
>    @Test
>    public void test() {
>
>      ServerBootstrap serverBootstrap = new ServerBootstrap(new
> DefaultLocalServerChannelFactory());
>
> serverBootstrap.setPipelineFactory(Channels.pipelineFactory(Channels.pipeline()));
>      serverBootstrap.bind(new LocalAddress("server"));
>
>      ClientBootstrap clientBootstrap = new ClientBootstrap(new
> DefaultLocalClientChannelFactory());
>      clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
>
>        @Override
>        public ChannelPipeline getPipeline() throws Exception {
>          ChannelPipeline pipeline = Channels.pipeline();
>          pipeline.addLast("close-handler", new
> SimpleChannelDownstreamHandler() {
>
>            @Override
>            public void closeRequested(ChannelHandlerContext ctx,
> ChannelStateEvent e)
>                throws Exception {
>              throw new RuntimeException("test");
>            }
>          });
>
>          pipeline.addLast("interceptor-up", new
> SimpleChannelUpstreamHandler() {
>
>            @Override
>            public void exceptionCaught(ChannelHandlerContext ctx,
> ExceptionEvent e) throws Exception {
>              // Can't tell that the exception was thrown during close
>              e.getCause().printStackTrace();
>              ctx.getChannel().close();
>            }
>          });
>          return pipeline;
>        }
>      });
>
>      ChannelFuture f = clientBootstrap.connect(new LocalAddress("server"));
>      f.awaitUninterruptibly();
>      // The channel is not closed and this will wait forever
>      f.getChannel().close().awaitUninterruptibly();
>    }
> }
> _______________________________________________
> netty-users mailing list
> netty-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/netty-users

-- 
Trustin Lee, http://gleamynode.net/



More information about the netty-users mailing list