docs: public void write() {
      // We record the start time to avoid spending too much time on writings
      long startOfCycle = System.nanoTime();
      long bytesWritten = 0;
  
      long nPacketsWritten = 0;
  
      while ((System.nanoTime() - startOfCycle - writeBatchTime.toNanos()) < 0
          && (bytesWritten < writeBatchSize.asBytes())) {
        OutgoingPacket outgoingPacket = outgoingPacketsToWrite.peek();
        if (outgoingPacket == null) {
          break;
        }
  
        int writeState = outgoingPacket.writeToChannel(socketChannel);
        if (writeState > 0) {
          // Partial writing, we would break since we could not write more data on socket.
          // But we have set the next start point of OutgoingPacket
          // Next time when the socket is writable, it will start from that point.
          break;
        } else if (writeState < 0) {
          LOG.severe("Something bad happened while writing to channel");
          selectHandler.handleError(socketChannel);
          return;
        } else {
          // writeState == 0, we fully write a outgoingPacket
          bytesWritten += outgoingPacket.size();
          nPacketsWritten++;
  
          outgoingPacketsToWrite.remove();
        }
      }
  
      totalPacketsWritten += nPacketsWritten;
      totalBytesWritten += bytesWritten;
  
      // Disable writing if there are nothing to send in buffer
      if (getOutstandingPackets() == 0) {
        disableWriting();
      }
    }