int sendBackups0(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; PartitionReplicaVersionManager versionManager = node.getPartitionService().getPartitionReplicaVersionManager(); ServiceNamespace namespace = versionManager.getServiceNamespace(op); long[] replicaVersions = versionManager.incrementPartitionReplicaVersions(op.getPartitionId(), namespace, 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 int sendMultipleBackups(BackupAwareOperation backupAwareOp, InternalPartition partition, long[] replicaVersions, int syncBackups, int totalBackups) { int sendSyncBackups = 0; Operation backupOp = getBackupOperation(backupAwareOp); if (!(backupOp instanceof TargetAware)) { // optimize common case: serialize operation once and send to multiple targets Data backupOpData = nodeEngine.getSerializationService().toData(backupOp); for (int replicaIndex = 1; replicaIndex <= totalBackups; replicaIndex++) { Address target = partition.getReplicaAddress(replicaIndex); if (target == null) { continue; } assertNoBackupOnPrimaryMember(partition, target); boolean isSyncBackup = replicaIndex <= syncBackups; Backup backup = newBackup(backupAwareOp, backupOpData, replicaVersions, replicaIndex, isSyncBackup); outboundOperationHandler.send(backup, target); if (isSyncBackup) { sendSyncBackups++; } } } else { for (int replicaIndex = 1; replicaIndex <= totalBackups; replicaIndex++) { int syncBackupSent = sendSingleBackup(backupAwareOp, partition, replicaVersions, syncBackups, replicaIndex); sendSyncBackups += syncBackupSent; } } return sendSyncBackups; }
private int sendSingleBackup(BackupAwareOperation backupAwareOp, InternalPartition partition, long[] replicaVersions, int syncBackups, int replica) { Operation backupOp = getBackupOperation(backupAwareOp); Address target = partition.getReplicaAddress(replica); if (target != null) { // Since there is only one backup, backup operation is sent to only one node. // If backup operation is converted to `Data`, there will be these operations as below: // - a temporary memory allocation (byte[]) for `Data` // - serialize backup operation to allocated memory // - copy the temporary allocated memory (backup operation data) to output while serializing `Backup` // In this flow, there are two redundant operations (allocating temporary memory and copying it to output). // So in this case (there is only one backup), we don't convert backup operation to `Data` as temporary // before `Backup` is serialized but backup operation is already serialized directly into output // without any unnecessary memory allocation and copy when it is used as object inside `Backup`. assertNoBackupOnPrimaryMember(partition, target); if (backupOp instanceof TargetAware) { ((TargetAware) backupOp).setTarget(target); } boolean isSyncBackup = syncBackups == 1; Backup backup = newBackup(backupAwareOp, backupOp, replicaVersions, 1, isSyncBackup); outboundOperationHandler.send(backup, target); if (isSyncBackup) { return 1; } } return 0; }
private int sendMultipleBackups(BackupAwareOperation backupAwareOp, InternalPartition partition, long[] replicaVersions, int syncBackups, int totalBackups) { int sendSyncBackups = 0; Operation backupOp = getBackupOperation(backupAwareOp); if (!(backupOp instanceof TargetAware)) { if (skipSendingBackupToTarget(partition, target)) { continue; Backup backup = newBackup(backupAwareOp, backupOpData, replicaVersions, replicaIndex, isSyncBackup); outboundOperationHandler.send(backup, target.address()); int syncBackupSent = sendSingleBackup(backupAwareOp, partition, replicaVersions, syncBackups, replicaIndex); sendSyncBackups += syncBackupSent;
private int sendSingleBackup(BackupAwareOperation backupAwareOp, InternalPartition partition, long[] replicaVersions, int syncBackups, int replica) { Operation backupOp = getBackupOperation(backupAwareOp); PartitionReplica target = partition.getReplica(replica); if (target != null) { if (skipSendingBackupToTarget(partition, target)) { return 0; } // Since there is only one backup, backup operation is sent to only one node. // If backup operation is converted to `Data`, there will be these operations as below: // - a temporary memory allocation (byte[]) for `Data` // - serialize backup operation to allocated memory // - copy the temporary allocated memory (backup operation data) to output while serializing `Backup` // In this flow, there are two redundant operations (allocating temporary memory and copying it to output). // So in this case (there is only one backup), we don't convert backup operation to `Data` as temporary // before `Backup` is serialized but backup operation is already serialized directly into output // without any unnecessary memory allocation and copy when it is used as object inside `Backup`. if (backupOp instanceof TargetAware) { ((TargetAware) backupOp).setTarget(target.address()); } boolean isSyncBackup = syncBackups == 1; Backup backup = newBackup(backupAwareOp, backupOp, replicaVersions, 1, isSyncBackup); outboundOperationHandler.send(backup, target.address()); if (isSyncBackup) { return 1; } } return 0; }
private void handleResponse(Operation op) throws Exception { int backupAcks = backupHandler.sendBackups(op); try { Object response = op.getResponse(); if (backupAcks > 0) { response = new NormalResponse(response, op.getCallId(), backupAcks, op.isUrgent()); } op.sendResponse(response); } catch (ResponseAlreadySentException e) { logOperationError(op, e); } }
private Operation getBackupOperation(BackupAwareOperation backupAwareOp) { Operation backupOp = backupAwareOp.getBackupOperation(); if (backupOp == null) { throw new IllegalArgumentException("Backup operation should not be null! " + backupAwareOp); } if (ASSERTION_ENABLED) { checkServiceNamespaces(backupAwareOp, backupOp); } 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()); backupOp.setNodeEngine(nodeEngine); return backupOp; }
this.backupHandler = new OperationBackupHandler(this, outboundOperationHandler);
private void handleResponse(Operation op) throws Exception { int backupAcks = backupHandler.sendBackups(op); try { Object response = op.getResponse(); if (backupAcks > 0) { response = new NormalResponse(response, op.getCallId(), backupAcks, op.isUrgent()); } op.sendResponse(response); } catch (ResponseAlreadySentException e) { logOperationError(op, e); } }
private Operation getBackupOperation(BackupAwareOperation backupAwareOp) { Operation backupOp = backupAwareOp.getBackupOperation(); if (backupOp == null) { throw new IllegalArgumentException("Backup operation should not be null! " + backupAwareOp); } if (ASSERTION_ENABLED) { checkServiceNamespaces(backupAwareOp, backupOp); } 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()); backupOp.setNodeEngine(nodeEngine); return backupOp; }
this.backupHandler = new OperationBackupHandler(this, outboundOperationHandler);
int sendBackups0(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; PartitionReplicaVersionManager versionManager = node.getPartitionService().getPartitionReplicaVersionManager(); ServiceNamespace namespace = versionManager.getServiceNamespace(op); long[] replicaVersions = versionManager.incrementPartitionReplicaVersions(op.getPartitionId(), namespace, 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); }