@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()); } }
@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); } } }
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()); } }); }
@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; }