[jboss-dev-forums] [Design of Messaging on JBoss (Messaging/JBoss)] - Re: Potential Netty problem with synchronously closing conne
trustin
do-not-reply at jboss.com
Mon May 11 04:55:15 EDT 2009
I was able to reproduce the issue finally using the following simple test code:
import java.net.InetAddress;
| import java.net.InetSocketAddress;
| import java.net.Socket;
| import java.util.concurrent.Executors;
| import java.util.concurrent.atomic.AtomicInteger;
|
| import org.jboss.netty.bootstrap.ServerBootstrap;
| import org.jboss.netty.channel.ChannelFactory;
| import org.jboss.netty.channel.ChannelHandlerContext;
| import org.jboss.netty.channel.ChannelPipelineCoverage;
| import org.jboss.netty.channel.ChannelStateEvent;
| import org.jboss.netty.channel.ExceptionEvent;
| import org.jboss.netty.channel.MessageEvent;
| import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
| import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
|
| public class Test {
|
| public static void main(String[] args) throws Throwable {
| ChannelFactory sf = new NioServerSocketChannelFactory(
| Executors.newCachedThreadPool(),
| Executors.newCachedThreadPool(), 1);
| ServerBootstrap sb = new ServerBootstrap(sf);
| sb.getPipeline().addLast("handler", new ServerHandler());
| sb.setOption("backlog", 1024);
| sb.bind(new InetSocketAddress(8080));
|
| InetAddress dstAddr = InetAddress.getByName("localhost");
| long startTime = System.currentTimeMillis();
| for (int i = 0; i < 1048576; i ++) {
| Socket s = new Socket(dstAddr, 8080);
| s.close();
| if ((i + 1) % 1000 == 0) {
| long endTime = System.currentTimeMillis();
| System.err.println(i + 1 + ": TOOK " + (endTime - startTime) + " MS");
| startTime = endTime;
| }
| }
|
| sb.releaseExternalResources();
| }
|
| @ChannelPipelineCoverage("all")
| static class ServerHandler extends SimpleChannelUpstreamHandler {
|
| private static final int THRESHOLD = 4;
| private final AtomicInteger cnt = new AtomicInteger();
| private final AtomicInteger lateCnt = new AtomicInteger();
| @Override
| public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
| throws Exception {
| if (cnt.incrementAndGet() > THRESHOLD) {
| lateCnt.incrementAndGet();
| }
| }
|
| @Override
| public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
| // Wait until the client closes the connection.
| }
|
| @Override
| public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
| throws Exception {
| if (cnt.decrementAndGet() == THRESHOLD) {
| System.err.println("LATE CLOSURES: " + lateCnt.getAndSet(0));
| }
| }
|
| @Override
| public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
| System.err.println(e);
| e.getCause().printStackTrace();
| e.getChannel().close();
| }
| }
| }
Sometimes, 'LATE CLOSURES' goes up to around 2000, which can lead to 'too many open files' for a normal user. I set the ulimit value of my local account to 10240, so I was not getting the error.
Let me try to optimize Netty so that it doesn't go up too much, but there's inevitable indeterminism because it's non-blocking I/O.
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4229970#4229970
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4229970
More information about the jboss-dev-forums
mailing list