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