public void whenNormalOperation(boolean partitionSpecific, boolean remoteCall) {
    BasicBackPressureService service = newEnabledBackPressureService();

    Operation op;
    if (partitionSpecific) {
      PartitionSpecificOperation partitionOp = new PartitionSpecificOperation();
      partitionOp.setPartitionId(0);
      op = partitionOp;
    } else {
      op = new GenericOperation();
      op.setPartitionId(-1);
    }

    Connection connection = null;
    if (remoteCall) {
      connection = mock(Connection.class);
      OperationAccessor.setConnection(op, connection);
    }

    int expected = SYNC_WINDOW - 1;
    for (int k = 0; k < SYNC_WINDOW; k++) {
      boolean result = service.isBackPressureNeeded(op);
      assertFalse("no back pressure expected", result);

      AtomicInteger syncDelay = service.getSyncDelay(connection, op.getPartitionId());
      assertEquals(expected, syncDelay.get());
      expected--;
    }

    boolean result = service.isBackPressureNeeded(op);
    assertTrue("back pressure expected", result);

    AtomicInteger syncDelay = service.getSyncDelay(connection, op.getPartitionId());
    assertValidSyncDelay(syncDelay);
  }
  public int backup(BackupAwareOperation backupAwareOp) throws Exception {
    int requestedSyncBackups = requestedSyncBackups(backupAwareOp);
    int requestedAsyncBackups = requestedAsyncBackups(backupAwareOp);
    int requestedTotalBackups = requestedTotalBackups(backupAwareOp);
    if (requestedTotalBackups == 0) {
      return 0;
    }

    Operation op = (Operation) backupAwareOp;
    InternalPartitionService partitionService = node.getPartitionService();
    long[] replicaVersions =
        partitionService.incrementPartitionReplicaVersions(
            op.getPartitionId(), requestedTotalBackups);

    boolean syncForced = backpressureRegulator.isSyncForced(backupAwareOp);

    int syncBackups = syncBackups(requestedSyncBackups, requestedAsyncBackups, syncForced);
    int asyncBackups = asyncBackups(requestedSyncBackups, requestedAsyncBackups, syncForced);

    // TODO: This could cause a problem with back pressure
    if (!op.returnsResponse()) {
      asyncBackups += syncBackups;
      syncBackups = 0;
    }

    if (syncBackups + asyncBackups == 0) {
      return 0;
    }

    return makeBackups(
        backupAwareOp, op.getPartitionId(), replicaVersions, syncBackups, asyncBackups);
  }
  private Backup newBackup(
      BackupAwareOperation backupAwareOp,
      Data backupOpData,
      long[] replicaVersions,
      int replicaIndex,
      boolean respondBack) {

    Operation op = (Operation) backupAwareOp;
    Backup backup = new Backup(backupOpData, op.getCallerAddress(), replicaVersions, respondBack);
    backup
        .setPartitionId(op.getPartitionId())
        .setReplicaIndex(replicaIndex)
        .setCallerUuid(nodeEngine.getLocalMember().getUuid());
    setCallId(backup, op.getCallId());

    return backup;
  }
  @Override
  public boolean send(Operation op, Address target) {
    checkNotNull(target, "Target is required!");

    if (thisAddress.equals(target)) {
      throw new IllegalArgumentException("Target is this node! -> " + target + ", op: " + op);
    }

    byte[] bytes = serializationService.toBytes(op);
    int partitionId = op.getPartitionId();
    Packet packet = new Packet(bytes, partitionId).setFlag(FLAG_OP);

    if (op.isUrgent()) {
      packet.setFlag(FLAG_URGENT);
    }

    ConnectionManager connectionManager = node.getConnectionManager();
    Connection connection = connectionManager.getOrConnect(target);
    return connectionManager.transmit(packet, connection);
  }
 int getPartitionIdForExecution(Operation op) {
   return op instanceof PartitionAwareOperation ? op.getPartitionId() : -1;
 }