netty: channel.close().awaitUninterruptibly() hangs
I am a new netty user. I am trying to close connections on server side and seeing that the code hangs at channel.close().awaitUninterruptibly(). I throw an exception from closeRequested() method to produce the problem (in sample code given below).
I am using netty 3.3.1-final. Any help would be helpful.
package abcd;
import java.net.InetSocketAddress; import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.group.DefaultChannelGroup; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
public class Experiment {
final static String host = "localhost";
final static int port = 61756;
final static ChannelGroup group = new DefaultChannelGroup();;
public static void main(String[] args) throws Exception {
ServerBootstrap serverBootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
serverBootstrap.setPipelineFactory(
new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("handler", new SimpleChannelHandler() {
@Override
public void closeRequested(ChannelHandlerContext ctx,
ChannelStateEvent e)
throws Exception {
System.out.println("close requested: " + e.getChannel());
throw new RuntimeException("test");
}
@Override
public void channelOpen(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
System.out.println("channel open: " + e.getChannel());
group.add(e.getChannel());
super.channelOpen(ctx, e);
}
@Override
public void channelClosed(ChannelHandlerContext ctx,
ChannelStateEvent e) throws Exception {
System.out.println("channel closed: " + e.getChannel());
super.channelClosed(ctx, e);
}
@Override
public void exceptionCaught(
ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
System.out.println("exception caught: " + e.getChannel());
}
});
return pipeline;
}
});
Channel serverChannel = serverBootstrap.bind(new InetSocketAddress(port));
ClientBootstrap clientBootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
return Channels.pipeline(new SimpleChannelHandler());
}
});
ChannelFuture f = clientBootstrap.connect(new InetSocketAddress(host, port));
f.awaitUninterruptibly();
serverChannel.close().awaitUninterruptibly();
System.out.println("after closing server channel");
for(Channel channel : group) {
// The channel is not closed and this will wait forever
channel.close().awaitUninterruptibly();
System.out.println("after closing client channel - this line is never printed");
}
System.out.println("end of program - this line is never printed");
}
}
About this issue
- Original URL
- State: closed
- Created 12 years ago
- Reactions: 1
- Comments: 24 (10 by maintainers)
Trustin - thanks for your help. Issue is resolved.
Summary of problem
channel.close().awaitUninterruptibly() was hanging because the worker thread that was suppose to close the channel was trapped in an infinite loop.
Due to an application bug, worker thread was trapped in an infinite loop in ReplayingDecoder during decoding one of the earlier received message.
Solution: Changed the application code to not use while loop and not trap the nio worker thread in a loop. This fixed our problem.