@Override
  public void messageSent(NextFilter nextFilter, final IoSession session, WriteRequest writeRequest)
      throws Exception {

    int maxWriteThroughput = this.maxWriteThroughput;
    // process the request if our max is greater than zero
    if (maxWriteThroughput > 0) {
      final State state = (State) session.getAttribute(STATE);
      long currentTime = System.currentTimeMillis();

      long suspendTime = 0;
      boolean firstWrite = false;
      synchronized (state) {
        state.writtenBytes += messageSizeEstimator.estimateSize(writeRequest.getMessage());
        if (!state.suspendedWrite) {
          if (state.writeStartTime == 0) {
            firstWrite = true;
            state.writeStartTime = currentTime - 1000;
          }

          long throughput = (state.writtenBytes * 1000 / (currentTime - state.writeStartTime));
          if (throughput >= maxWriteThroughput) {
            suspendTime =
                Math.max(
                    0,
                    state.writtenBytes * 1000 / maxWriteThroughput
                        - (firstWrite ? 0 : currentTime - state.writeStartTime));

            state.writtenBytes = 0;
            state.writeStartTime = 0;
            state.suspendedWrite = suspendTime != 0;
          }
        }
      }

      if (suspendTime != 0) {
        log.trace("Suspending write");
        session.suspendWrite();
        scheduledExecutor.schedule(
            new Runnable() {
              public void run() {
                synchronized (state) {
                  state.suspendedWrite = false;
                }
                session.resumeWrite();
                log.trace("Resuming write");
              }
            },
            suspendTime,
            TimeUnit.MILLISECONDS);
      }
    }

    nextFilter.messageSent(session, writeRequest);
  }
 @Override
 public void sessionCreated(IoSession session) throws Exception {
   session.suspendRead();
   session.suspendWrite();
 }