@Override
  public void run() throws Exception {
    if (!valid) {
      onExecutionFailure(
          new IllegalStateException("Wrong target! " + toString() + " cannot be processed!"));
      return;
    }

    NodeEngine nodeEngine = getNodeEngine();

    if (backupOp == null && backupOpData != null) {
      backupOp = nodeEngine.getSerializationService().toObject(backupOpData);
    }

    if (backupOp != null) {
      ensureBackupOperationInitialized();

      backupOp.beforeRun();
      backupOp.run();
      backupOp.afterRun();
    }

    InternalPartitionService partitionService = nodeEngine.getPartitionService();
    partitionService.updatePartitionReplicaVersions(
        getPartitionId(), replicaVersions, getReplicaIndex());
  }
  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);
  }
  @Override
  public boolean isCallTimedOut(Operation op) {
    // Join operations should not be checked for timeout
    // because caller is not member of this cluster
    // and can have a different clock.
    if (!op.returnsResponse() || isJoinOperation(op)) {
      return false;
    }

    long callTimeout = op.getCallTimeout();
    long invocationTime = op.getInvocationTime();
    long expireTime = invocationTime + callTimeout;

    if (expireTime <= 0 || expireTime == Long.MAX_VALUE) {
      return false;
    }

    ClusterClock clusterClock = nodeEngine.getClusterService().getClusterClock();
    long now = clusterClock.getClusterTime();
    if (expireTime < now) {
      return true;
    }

    return false;
  }
  public void clearInternal() {
    try {
      Operation clearOperation = operationProvider.createClearOperation(name);
      clearOperation.setServiceName(SERVICE_NAME);
      BinaryOperationFactory factory = new BinaryOperationFactory(clearOperation, getNodeEngine());
      Map<Integer, Object> resultMap =
          operationService.invokeOnAllPartitions(SERVICE_NAME, factory);

      int numberOfAffectedEntries = 0;
      for (Object object : resultMap.values()) {
        numberOfAffectedEntries += (Integer) object;
      }

      MemberSelector selector =
          MemberSelectors.and(LITE_MEMBER_SELECTOR, NON_LOCAL_MEMBER_SELECTOR);
      for (Member member : getNodeEngine().getClusterService().getMembers(selector)) {
        operationService.invokeOnTarget(
            SERVICE_NAME, new ClearOperation(name), member.getAddress());
      }

      if (numberOfAffectedEntries > 0) {
        publishMapEvent(numberOfAffectedEntries, EntryEventType.CLEAR_ALL);
      }
    } catch (Throwable t) {
      throw rethrow(t);
    }
  }
  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 void execute(Operation op) {
   String executorName = op.getExecutorName();
   if (executorName == null) {
     int partitionId = getPartitionIdForExecution(op);
     boolean hasPriority = op.isUrgent();
     execute(op, partitionId, hasPriority);
   } else {
     executeOnExternalExecutor(op, executorName);
   }
 }
 public void run() throws Exception {
   for (Operation op : opList) {
     op.setNodeEngine(getNodeEngine())
         .setServiceName(getServiceName())
         .setPartitionId(getPartitionId());
     op.beforeRun();
     op.run();
     op.afterRun();
   }
   getOrCreateContainer().unlock(dataKey, caller, threadId);
 }
  @Override
  public final void process() throws Exception {
    final ClientEndpoint endpoint = getEndpoint();
    Operation op = prepareOperation();
    op.setCallerUuid(endpoint.getUuid());

    InvocationBuilder builder =
        getInvocationBuilder(op).setResultDeserialized(false).setExecutionCallback(this);

    builder.invoke();
  }
 private Data getBackupOperationData(BackupAwareOperation backupAwareOp) {
   Operation backupOp = backupAwareOp.getBackupOperation();
   if (backupOp == null) {
     throw new IllegalArgumentException("Backup operation should not be null! " + backupAwareOp);
   }
   Operation op = (Operation) backupAwareOp;
   // set service name of backup operation.
   // if getServiceName() method is overridden to return the same name
   // then this will have no effect.
   backupOp.setServiceName(op.getServiceName());
   return nodeEngine.getSerializationService().toData(backupOp);
 }
  @Override
  protected void toString(StringBuilder sb) {
    super.toString(sb);

    sb.append(", syncReplicaIndex=").append(syncReplicaIndex);
    sb.append(", sync=").append(sync);
  }
  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;
  }
 private Collection<Operation> prepareMigrationTasks() {
   NodeEngineImpl nodeEngine = (NodeEngineImpl) getNodeEngine();
   final PartitionReplicationEvent replicationEvent =
       new PartitionReplicationEvent(migrationInfo.getPartitionId(), 0);
   final PartitionMigrationEvent migrationEvent =
       new PartitionMigrationEvent(MigrationEndpoint.SOURCE, migrationInfo.getPartitionId());
   final Collection<Operation> tasks = new LinkedList<Operation>();
   for (ServiceInfo serviceInfo : nodeEngine.getServiceInfos(MigrationAwareService.class)) {
     MigrationAwareService service = (MigrationAwareService) serviceInfo.getService();
     service.beforeMigration(migrationEvent);
     final Operation op = service.prepareReplicationOperation(replicationEvent);
     if (op != null) {
       op.setServiceName(serviceInfo.getName());
       tasks.add(op);
     }
   }
   return tasks;
 }
  @Override
  protected void toString(StringBuilder sb) {
    super.toString(sb);

    sb.append(", backupOp=").append(backupOp);
    sb.append(", backupOpData=").append(backupOpData);
    sb.append(", originalCaller=").append(originalCaller);
    sb.append(", version=").append(Arrays.toString(replicaVersions));
    sb.append(", sync=").append(sync);
  }
  @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);
  }
 @Override
 public void logError(Throwable e) {
   if (backupOp != null) {
     // Be sure that backup operation is initialized.
     // If there is an exception before `run` (for example caller is not valid anymore),
     // backup operation is initialized. So, we are initializing it here ourselves.
     ensureBackupOperationInitialized();
     backupOp.logError(e);
   } else {
     ReplicaErrorLogger.log(e, getLogger());
   }
 }
Exemple #16
0
  @Override
  public void run() throws Exception {
    if (!valid) {
      return;
    }
    final NodeEngine nodeEngine = getNodeEngine();
    final PartitionServiceImpl partitionService =
        (PartitionServiceImpl) nodeEngine.getPartitionService();
    partitionService.updatePartitionReplicaVersions(
        getPartitionId(), replicaVersions, getReplicaIndex());

    if (backupOp != null) {
      backupOp.setNodeEngine(nodeEngine);
      backupOp.setResponseHandler(ResponseHandlerFactory.createEmptyResponseHandler());
      backupOp.setCallerUuid(getCallerUuid());
      OperationAccessor.setCallerAddress(backupOp, getCallerAddress());
      OperationAccessor.setInvocationTime(backupOp, Clock.currentTimeMillis());

      final OperationService operationService = nodeEngine.getOperationService();
      operationService.runOperation(backupOp);
    }
  }
    @Override
    public void run(Operation task) {
      operations.add(task);

      this.currentTask = task;
      try {
        task.run();
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        currentTask = null;
      }
    }
 @Override
 public void onExecutionFailure(Throwable e) {
   if (backupOp != null) {
     try {
       // Be sure that backup operation is initialized.
       // If there is an exception before `run` (for example caller is not valid anymore),
       // backup operation is initialized. So, we are initializing it here ourselves.
       ensureBackupOperationInitialized();
       backupOp.onExecutionFailure(e);
     } catch (Throwable t) {
       getLogger().warning("While calling operation.onFailure(). op: " + backupOp, t);
     }
   }
 }
Exemple #19
0
  protected void startClusterMerge(final Address targetAddress) {
    ClusterServiceImpl clusterService = node.clusterService;

    if (!prepareClusterState(clusterService)) {
      return;
    }

    OperationService operationService = node.nodeEngine.getOperationService();
    Collection<Member> memberList = clusterService.getMembers();
    for (Member member : memberList) {
      if (!member.localMember()) {
        Operation op = new MergeClustersOperation(targetAddress);
        operationService.invokeOnTarget(ClusterServiceImpl.SERVICE_NAME, op, member.getAddress());
      }
    }

    Operation mergeClustersOperation = new MergeClustersOperation(targetAddress);
    mergeClustersOperation
        .setNodeEngine(node.nodeEngine)
        .setService(clusterService)
        .setOperationResponseHandler(createEmptyResponseHandler());
    operationService.runOperationOnCallingThread(mergeClustersOperation);
  }
  @Test
  public void whenGeneric() {
    initExecutor();

    final AtomicReference<Thread> executingThread = new AtomicReference<Thread>();

    Operation op =
        new Operation() {
          @Override
          public void run() throws Exception {
            executingThread.set(Thread.currentThread());
          }
        };
    executor.execute(op.setPartitionId(-1));

    assertTrueEventually(
        new AssertTask() {
          @Override
          public void run() throws Exception {
            assertInstanceOf(GenericOperationThread.class, executingThread.get());
          }
        });
  }
Exemple #21
0
  @Override
  public void afterRun() throws Exception {
    if (sync && getCallId() != 0 && originalCaller != null) {
      final NodeEngineImpl nodeEngine = (NodeEngineImpl) getNodeEngine();
      final long callId = getCallId();
      final InternalOperationService operationService = nodeEngine.operationService;

      if (!nodeEngine.getThisAddress().equals(originalCaller)) {
        BackupResponse backupResponse = new BackupResponse(callId, backupOp.isUrgent());
        operationService.send(backupResponse, originalCaller);
      } else {
        operationService.notifyBackupCall(callId);
      }
    }
  }
  @Override
  @SuppressWarnings("unchecked")
  public <E> InternalCompletableFuture<E> invokeOnTarget(
      String serviceName, Operation op, Address target) {
    op.setServiceName(serviceName);

    return new TargetInvocation(
            invocationContext,
            op,
            target,
            DEFAULT_TRY_COUNT,
            DEFAULT_TRY_PAUSE_MILLIS,
            DEFAULT_CALL_TIMEOUT,
            DEFAULT_DESERIALIZE_RESULT)
        .invoke();
  }
 private void ensureBackupOperationInitialized() {
   if (backupOp.getNodeEngine() == null) {
     backupOp.setNodeEngine(getNodeEngine());
     backupOp.setPartitionId(getPartitionId());
     backupOp.setReplicaIndex(getReplicaIndex());
     backupOp.setCallerUuid(getCallerUuid());
     OperationAccessor.setCallerAddress(backupOp, getCallerAddress());
     OperationAccessor.setInvocationTime(backupOp, Clock.currentTimeMillis());
     backupOp.setOperationResponseHandler(createEmptyResponseHandler());
   }
 }
  @Override
  @SuppressWarnings("unchecked")
  public <E> InternalCompletableFuture<E> invokeOnPartition(
      String serviceName, Operation op, int partitionId) {
    op.setServiceName(serviceName)
        .setPartitionId(partitionId)
        .setReplicaIndex(DEFAULT_REPLICA_INDEX);

    return new PartitionInvocation(
            invocationContext,
            op,
            DEFAULT_TRY_COUNT,
            DEFAULT_TRY_PAUSE_MILLIS,
            DEFAULT_CALL_TIMEOUT,
            DEFAULT_DESERIALIZE_RESULT)
        .invoke();
  }
  @Override
  public void afterRun() throws Exception {
    if (!valid || !sync || getCallId() == 0 || originalCaller == null) {
      return;
    }

    NodeEngineImpl nodeEngine = (NodeEngineImpl) getNodeEngine();
    long callId = getCallId();
    OperationServiceImpl operationService = (OperationServiceImpl) nodeEngine.getOperationService();

    if (nodeEngine.getThisAddress().equals(originalCaller)) {
      operationService.getInvocationsRegistry().notifyBackupComplete(callId);
    } else {
      BackupResponse backupResponse = new BackupResponse(callId, backupOp.isUrgent());
      operationService.send(backupResponse, originalCaller);
    }
  }
  @Override
  @SuppressWarnings("unchecked")
  public <V> void asyncInvokeOnPartition(
      String serviceName, Operation op, int partitionId, ExecutionCallback<V> callback) {
    op.setServiceName(serviceName)
        .setPartitionId(partitionId)
        .setReplicaIndex(DEFAULT_REPLICA_INDEX);

    InvocationFuture future =
        new PartitionInvocation(
                invocationContext,
                op,
                DEFAULT_TRY_COUNT,
                DEFAULT_TRY_PAUSE_MILLIS,
                DEFAULT_CALL_TIMEOUT,
                DEFAULT_DESERIALIZE_RESULT)
            .invokeAsync();

    if (callback != null) {
      future.andThen(callback);
    }
  }
  @Override
  protected void toString(StringBuilder sb) {
    super.toString(sb);

    sb.append(", name=").append(name);
  }
 @Override
 protected void writeInternal(ObjectDataOutput out) throws IOException {
   super.writeInternal(out);
   out.writeUTF(objectId);
   out.writeInt(amount);
 }
 @Override
 protected void readInternal(ObjectDataInput in) throws IOException {
   super.readInternal(in);
   objectId = in.readUTF();
   amount = in.readInt();
 }
 int getPartitionIdForExecution(Operation op) {
   return op instanceof PartitionAwareOperation ? op.getPartitionId() : -1;
 }