[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