@Override
 public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
   if (channelBuffer.refCnt() >= 1) {
     channelBuffer.release();
   }
   super.handlerRemoved(ctx);
 }
    @Override
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
      Channel channel = new NettyChannel(ctx);

      final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
      LOGGER.info("CLIENT : CLOSE {}", remoteAddress);
      closeChannel(channel);
      super.close(ctx, promise);

      if (channelEventListener != null) {
        putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
      }
    }
    @Override
    public void connect(
        ChannelHandlerContext ctx,
        SocketAddress remoteAddress,
        SocketAddress localAddress,
        ChannelPromise promise)
        throws Exception {
      final String local = localAddress == null ? "UNKNOW" : localAddress.toString();
      final String remote = remoteAddress == null ? "UNKNOW" : remoteAddress.toString();
      LOGGER.info("CLIENT : CONNECT  {} => {}", local, remote);
      super.connect(ctx, remoteAddress, localAddress, promise);

      if (channelEventListener != null) {
        assert remoteAddress != null;
        putRemotingEvent(
            new RemotingEvent(
                RemotingEventType.CONNECT, remoteAddress.toString(), new NettyChannel(ctx)));
      }
    }
 @Override
 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
   if (bufferedMode && outboundChannel.isActive()) {
     flushedBuffer = true;
     outboundChannel
         .writeAndFlush(interceptor.intercept(ctx, channelBuffer, logger))
         .addListener(
             new ChannelFutureListener() {
               @Override
               public void operationComplete(ChannelFuture future) throws Exception {
                 if (future.isSuccess()) {
                   channelBuffer.clear();
                 } else {
                   future.channel().close();
                 }
               }
             });
   }
   super.channelReadComplete(ctx);
 }
 @Override
 public void channelActive(ChannelHandlerContext ctx) throws Exception {
   super.channelActive(ctx);
   assertQueueEmpty(queue);
   Assert.assertTrue("Should be writable", ctx.channel().isWritable());
 }
 @Override
 public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
   this.channelBuffer = Unpooled.directBuffer(bufferedCapacity);
   super.handlerAdded(ctx);
 }