use of org.syncany.plugins.transfer.to.ActionTO in project syncany by syncany.
the class RemoteTransaction method moveToFinalLocation.
/**
* This method constitutes the second step in the committing process. All files have been uploaded, and they are
* now moved to their final location.
*/
private void moveToFinalLocation() throws StorageException {
for (ActionTO action : transactionTO.getActions()) {
if (action.getType().equals(ActionType.UPLOAD)) {
RemoteFile tempRemoteFile = action.getTempRemoteFile();
RemoteFile finalRemoteFile = action.getRemoteFile();
logger.log(Level.INFO, "- Moving temp. file {0} to final location {1} ...", new Object[] { tempRemoteFile, finalRemoteFile });
transferManager.move(tempRemoteFile, finalRemoteFile);
action.setStatus(ActionStatus.DONE);
}
}
}
use of org.syncany.plugins.transfer.to.ActionTO in project syncany by syncany.
the class RemoteTransaction method uploadAndMoveToTempLocation.
/**
* This method performs the first step for all files in the committing process.
* For UPLOADs, this is uploading the file to the temporary remote location.
* For DELETEs, this is moving the file from the original remote location to a temporary remote location.
* If this is a transaction that is being resumed, the {@link ActionStatus} will show that this part has
* already been done. In this case, we do not repeat it.
*
* This is the expensive part of the committing process, when we are talking about I/O. Hence this is also
* the most likely part to be interrupted on weak connections.
*/
private void uploadAndMoveToTempLocation() throws StorageException {
TransactionStats stats = gatherTransactionStats();
int uploadFileIndex = 0;
for (ActionTO action : transactionTO.getActions()) {
if (action.getStatus().equals(ActionStatus.UNSTARTED)) {
// If we are resuming, this has not been started yet.
RemoteFile tempRemoteFile = action.getTempRemoteFile();
if (action.getType().equals(ActionType.UPLOAD)) {
// The action is an UPLOAD, upload file to temporary remote location
File localFile = action.getLocalTempLocation();
long localFileSize = localFile.length();
eventBus.post(new UpUploadFileInTransactionSyncExternalEvent(config.getLocalDir().getAbsolutePath(), ++uploadFileIndex, stats.totalUploadFileCount, localFileSize, stats.totalUploadSize));
logger.log(Level.INFO, "- Uploading {0} to temp. file {1} ...", new Object[] { localFile, tempRemoteFile });
transferManager.upload(localFile, tempRemoteFile);
action.setStatus(ActionStatus.STARTED);
} else if (action.getType().equals(ActionType.DELETE)) {
// The action is a DELETE, move file to temporary remote location.
RemoteFile remoteFile = action.getRemoteFile();
try {
logger.log(Level.INFO, "- Moving {0} to temp. file {1} ...", new Object[] { remoteFile, tempRemoteFile });
transferManager.move(remoteFile, tempRemoteFile);
} catch (StorageMoveException e) {
logger.log(Level.INFO, " -> FAILED (don't care!), because the remoteFile does not exist: " + remoteFile);
}
action.setStatus(ActionStatus.STARTED);
}
}
}
}
use of org.syncany.plugins.transfer.to.ActionTO in project syncany by syncany.
the class TransactionAwareFeatureTransferManager method getTransactionsByClient.
/**
* This function returns a list of all remote transaction files that belong to the client. If blocking transactions exist,
* this methods returns null, because we are not allowed to proceed.
*/
public List<TransactionRemoteFile> getTransactionsByClient(String client) throws StorageException {
Objects.requireNonNull(config, "Cannot get transactions if config is null.");
Map<TransactionTO, TransactionRemoteFile> transactions = retrieveRemoteTransactions();
List<TransactionRemoteFile> transactionsByClient = new ArrayList<TransactionRemoteFile>();
for (TransactionTO potentiallyResumableTransaction : transactions.keySet()) {
boolean isCancelledOwnTransaction = potentiallyResumableTransaction.getMachineName().equals(config.getMachineName());
if (isCancelledOwnTransaction) {
transactionsByClient.add(transactions.get(potentiallyResumableTransaction));
} else {
// Check for blocking transactions
for (ActionTO action : potentiallyResumableTransaction.getActions()) {
if (action.getType().equals(ActionType.DELETE)) {
return null;
}
}
}
}
return transactionsByClient;
}
use of org.syncany.plugins.transfer.to.ActionTO in project syncany by syncany.
the class TransactionAwareFeatureTransferManager method rollbackActions.
/**
* Adds the opposite actions (rollback actions) for the given unfinished actions
* to the rollback transaction.
*/
private void rollbackActions(List<ActionTO> unfinishedActions) throws StorageException {
for (ActionTO action : unfinishedActions) {
logger.log(Level.INFO, "- Needs to be rolled back: " + action);
switch(action.getType()) {
case UPLOAD:
delete(action.getRemoteFile());
delete(action.getTempRemoteFile());
break;
case DELETE:
try {
logger.log(Level.INFO, "- Rollback action: Moving " + action.getTempRemoteFile().getName() + " to " + action.getRemoteFile().getName());
move(action.getTempRemoteFile(), action.getRemoteFile());
} catch (StorageMoveException e) {
logger.log(Level.WARNING, "Restoring deleted file failed. This might be a problem if the original: " + action.getRemoteFile() + " also does not exist.", e);
}
break;
default:
throw new RuntimeException("Transaction contains invalid type: " + action.getType() + ". This should not happen.");
}
}
}
use of org.syncany.plugins.transfer.to.ActionTO in project syncany by syncany.
the class TransactionAwareFeatureTransferManager method cleanTransactions.
/**
* Checks if any transactions of the local machine were not completed and performs
* a rollback if any transactions were found. The rollback itself is performed in
* a transaction.
*
* <p>The method uses {@link #retrieveRemoteTransactions()} to download all transaction
* files and then rolls back the local machines's transactions:
*
* <ul>
* <li>Files in the transaction marked "UPLOAD" are deleted.</li>
* <li>Files in the transaction marked "DELETE" are moved back to their original place.</li>
* </ul>
*
* @throws BlockingTransfersException if we cannot proceed (Deleting transaction by another client exists).
*/
public void cleanTransactions() throws StorageException, BlockingTransfersException {
Objects.requireNonNull(config, "Cannot clean transactions if config is null.");
Map<TransactionTO, TransactionRemoteFile> transactions = retrieveRemoteTransactions();
boolean noBlockingTransactionsExist = true;
for (TransactionTO potentiallyCancelledTransaction : transactions.keySet()) {
boolean isCancelledOwnTransaction = potentiallyCancelledTransaction.getMachineName().equals(config.getMachineName());
// If this transaction is from our machine, delete all permanent or temporary files in this transaction.
if (isCancelledOwnTransaction) {
rollbackSingleTransaction(potentiallyCancelledTransaction, transactions.get(potentiallyCancelledTransaction));
} else if (noBlockingTransactionsExist) {
// Only check if we have not yet found deleting transactions by others
for (ActionTO action : potentiallyCancelledTransaction.getActions()) {
if (action.getType().equals(ActionType.DELETE)) {
noBlockingTransactionsExist = false;
}
}
}
}
logger.log(Level.INFO, "Done rolling back previous transactions.");
if (!noBlockingTransactionsExist) {
throw new BlockingTransfersException();
}
}
Aggregations