title: Netty Channel fail when write and flush too many and too fast
body: <p>When I write a producer to publish message to my server. I've seen this: <br/></p>
  
  <pre><code>java.io.IOException: Connection reset by peer
  at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
  at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
  at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
  at sun.nio.ch.IOUtil.read(IOUtil.java:192)
  at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:384)
  at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:447)
  at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:881)
  at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:242)
  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:119)
  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
  at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
  at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111)
  at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
  at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p>I've searched all around and was told that because of channel is closed.
  But, in my code. I'm just close my channel when my channel pool destroy the channel. <br>
  Here my code: <br></p>
  
  <pre><code>public static class ChannelFactory implements PoolableObjectFactory&lt;Channel&gt; {
  
      private final Bootstrap bootstrap;
      private String host;
      private int port;
  
      public ChannelFactory(Bootstrap bootstrap, String host, int port) {
          this.bootstrap = bootstrap;
          this.host = host;
          this.port = port;
      }
  
      @Override
      public Channel makeObject() throws Exception {
          System.out.println("Create new channel!!!");
          bootstrap.validate();
          return bootstrap.connect(host, port).channel();
      }
  
      @Override
      public void destroyObject(Channel channel) throws Exception {
          ChannelFuture close = channel.close();
          if (close.isSuccess()) {
              System.out.println(channel + " close successfully");
          }
      }
  
      @Override
      public boolean validateObject(Channel channel) {
          System.out.println("Validate object");
          return (channel.isOpen());
      }
  
      @Override
      public void activateObject(Channel channel) throws Exception {
          System.out.println(channel + " is activated");
      }
  
      @Override
      public void passivateObject(Channel channel) throws Exception {
          System.out.println(channel + " is passivated");
      }
  
      /**
       * @return the host
       */
      public String getHost() {
          return host;
      }
  
      /**
       * @param host the host to set
       * @return
       */
      public ChannelFactory setHost(String host) {
          this.host = host;
          return this;
      }
  
      /**
       * @return the port
       */
      public int getPort() {
          return port;
      }
  
      /**
       * @param port the port to set
       * @return
       */
      public ChannelFactory setPort(int port) {
          this.port = port;
          return this;
      }
  
  }
  </code></pre>
  
  <p>And here is my Runner: <br/></p>
  
  <pre><code>public static class Runner implements Runnable {
  
      private Channel channel;
      private ButtyMessage message;
      private MyChannelPool channelPool;
  
      public Runner(MyChannelPool channelPool, Channel channel, ButtyMessage message) {
          this.channel = channel;
          this.message = message;
          this.channelPool = channelPool;
      }
  
      @Override
      public void run() {
          channel.writeAndFlush(message.content()).syncUninterruptibly().addListener(new ChannelFutureListener() {
  
              @Override
              public void operationComplete(ChannelFuture future) throws Exception {
                  channelPool.returnObject(future.channel());
              }
          });
      }
  
  }
  </code></pre>
  
  <p>And my main: <br/></p>
  
  <pre><code>public static void main(String[] args) throws InterruptedException {
  
      final String host = "127.0.0.1";
      final int port = 8080;
      int jobSize = 100;
      int jobNumber = 10000;
      final Bootstrap b = func(host, port);
  
      final MyChannelPool channelPool = new MyChannelPool(new ChannelFactory(b, host, port));
  
      ExecutorService threadPool = Executors.newFixedThreadPool(1);
      for (int i = 0; i &lt; jobNumber; i++) {
          try {
              threadPool.execute(new Runner(channelPool, channelPool.borrowObject(), new ButtyMessage()));
          } catch (Exception ex) {
              System.out.println("ex = " + ex.getMessage());
          }
      }
  }
  </code></pre>
  
  <p>With <code>ButtyMessage</code> extends <code>ByteBufHolder</code>. <br/>
  In my Runner class, if I sleep(10) after <code>writeAndFlush</code> it run quite OK. But I don't want to reply on sleep. So I use <code>ChannelFutureListener</code>, but the result is bad. If I send about 1000 to 10.000 messages, it will crash and throw exception above. Is there any way to avoid this? <br/>
  <br/>
  Thanks all. <br/>
  Sorry for my bad explain and my English :)</p>