Agree with Norman, check future.cause() - if something is going wrong, the 
information is there but you're not checking it.

But there's a simpler explanation.  In your loop you do this:

if (!client.isWritable()) {
  Thread.sleep(5000);
}

if (client.isWritable()) {
   System.out.println("send " + i);
   //...send the request
}

If client.isWritable() is false on the second test, you never send the 
request.  So most likely your own code is skipping sending it.  There's 
nothing particularly special about 5 seconds - a lot of time for the 
computer, but you're also banging very hard on everything in your OS 
between your code and the network card.

You also might have limit_conn somewhere in your NginX config, which tells 
it to refuse more than *n* connections from any one address.  I don't 
remember if it's in the out-of-the-box NginX config, but it's a very common 
defense against simple denial of service attacks that use a few hosts to 
tie up a lot of connections.

There's a better pattern for looping in a world of async callbacks - and it 
will get you out of your isWritable() tests completely.  Roughly this:

class RepeatedSender implements ChannelFutureListener {
  final int max;
  int requestId;
  RepeatedSender(int max) {  this.max = max; }
  
  public void operationComplete(ChannelFuture future) {
     if (future.cause()) {
        future.cause().printStackTrace();
        return; // something is wrong, so quit.
     }
     if (++requestId < max) {
        sendRequest();
     }
  }

  void sendRequest () {
    HttpRequest req = // create the request...
    client.write(req).addListener(this);
  }
}

new RepeatedSender(500).sendRequest();

Now, what this does is chain up the requests - so each one is not sent 
until the previous one has been flushed to the socket.  So, no loops and no 
writability tests because you are only called when the channel is not busy.

If you wanted to, say, parallelize this to send more concurrent requests, 
you'd just create, say, an EventLoopGroup with 5 threads and create 5 
RepeatedSender(100) and call start on each one.

In other words, usually when you want to write a loop in async, callback 
based code, you're not going to use a for- or while-loop.  Instead, you're 
going to write something that gets called back when one batch of work is 
finished, and it then dispatches the next batch work until it's done.  It 
feels more like writing recursion than looping.

-Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/f4ba9336-f59f-4403-8717-d46d141b3885%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to