From 8f1aff6a0c15d836435f8227f52745dff0a5f6ad Mon Sep 17 00:00:00 2001 From: Herve Eruam Date: Mon, 21 Oct 2024 12:10:01 +0200 Subject: [PATCH] Move handleOpsFileAccessError down to avoid difficult to review git diff. --- .../propagation/executor/executorworker.cpp | 224 +++++++++--------- 1 file changed, 111 insertions(+), 113 deletions(-) diff --git a/src/libsyncengine/propagation/executor/executorworker.cpp b/src/libsyncengine/propagation/executor/executorworker.cpp index 09f0ca185..81676af51 100644 --- a/src/libsyncengine/propagation/executor/executorworker.cpp +++ b/src/libsyncengine/propagation/executor/executorworker.cpp @@ -277,8 +277,6 @@ void ExecutorWorker::initSyncFileItem(SyncOpPtr syncOp, SyncFileItem &syncItem) syncItem.setInstruction(SyncFileInstruction::Put); } } - - return; } void ExecutorWorker::logCorrespondingNodeErrorMsg(const SyncOpPtr syncOp) { @@ -304,117 +302,6 @@ void ExecutorWorker::setProgressComplete(const SyncOpPtr syncOp, SyncFileStatus _syncPal->setProgressComplete(relativeLocalFilePath, status); } -ExitInfo ExecutorWorker::handleOpsExecutionError(SyncOpPtr syncOp, ExitInfo opsExitInfo) { - assert((syncOp && !opsExitInfo) && "syncOp is nullptr in ExecutorWorker::handleOpsExecutionError"); - if (!syncOp) { - LOG_WARN(_logger, "syncOp is nullptr in ExecutorWorker::handleOpsExecutionError"); - return ExitCode::DataError; - } - if (opsExitInfo) { - return opsExitInfo; - } - - // Handle specific errors - switch (static_cast(opsExitInfo)) { - case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError)): - case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::MoveToTrashFailed)): { - return handleOpsFileAccessError(syncOp, opsExitInfo); - } - default: { - break; - } - }; - LOG_WARN(_logger, - "Unhandled error in ExecutorWorker::handleOpsExecutionError: " << opsExitInfo.code() << " " << opsExitInfo.cause()); - return opsExitInfo; -} - -ExitInfo ExecutorWorker::handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo opsExitInfo) { - if (syncOp->targetSide() == ReplicaSide::Local && syncOp->type() == OperationType::Create) { - // The item does not exist yet locally, we will only tmpBlacklist the remote item - _syncPal->handleAccessDeniedItem(syncOp->affectedNode()->getPath()); - } else { - // Both local and remote item will be temporarily blacklisted - auto localNode = syncOp->targetSide() == ReplicaSide::Remote ? syncOp->affectedNode() : syncOp->correspondingNode(); - if (!localNode) return ExitCode::LogicError; - SyncPath relativeLocalFilePath = localNode->getPath(); - SyncPath absoluteLocalFilePath = _syncPal->localPath() / relativeLocalFilePath; - NodeId localNodeId = localNode->id().has_value() ? *localNode->id() : NodeId(); - _syncPal->handleAccessDeniedItem(absoluteLocalFilePath, localNodeId, opsExitInfo.cause()); - _syncPal->blacklistTemporarily(syncOp->affectedNode()->id().has_value() ? *syncOp->affectedNode()->id() : std::string(), - syncOp->nodePath(ReplicaSide::Local), otherSide(syncOp->targetSide())); - Error error(_syncPal->syncDbId(), "", "", NodeType::Directory, - _syncPal->localPath() / syncOp->nodePath(ReplicaSide::Local), ConflictType::None, InconsistencyType::None, - CancelType::None, "", opsExitInfo.code(), opsExitInfo.cause()); - _syncPal->addError(error); - - if (!affectedUpdateTree(syncOp)->deleteNode(syncOp->affectedNode())) { - LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node name=" - << SyncName2WStr(syncOp->affectedNode()->name()).c_str()); - return ExitCode::DataError; - } - - if (syncOp->correspondingNode()) { - if (!targetUpdateTree(syncOp)->deleteNode(syncOp->correspondingNode())) { - LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node name=" - << SyncName2WStr(syncOp->correspondingNode()->name()).c_str()); - return ExitCode::DataError; - } - } - } - - removeDependentOps(syncOp); - return ExitCode::Ok; -} - -ExitInfo ExecutorWorker::removeDependentOps(SyncOpPtr syncOp) { - auto localNode = syncOp->affectedNode()->side() == ReplicaSide::Local ? syncOp->affectedNode() : syncOp->correspondingNode(); - auto remoteNode = - syncOp->affectedNode()->side() == ReplicaSide::Remote ? syncOp->affectedNode() : syncOp->correspondingNode(); - - std::list dependentOps; - for (const auto &opId: _opList) { - SyncOpPtr syncOp2 = _syncPal->_syncOps->getOp(opId); - if (!syncOp2) { - LOGW_SYNCPAL_WARN(_logger, L"Operation doesn't exist anymore: id=" << opId); - continue; - } - auto localNode2 = - syncOp2->affectedNode()->side() == ReplicaSide::Local ? syncOp2->affectedNode() : syncOp2->correspondingNode(); - auto remoteNode2 = - syncOp2->affectedNode()->side() == ReplicaSide::Remote ? syncOp2->affectedNode() : syncOp2->correspondingNode(); - SyncName nodeName = localNode2 ? localNode2->name() : SyncName(); - nodeName = (nodeName.empty() && remoteNode2) ? remoteNode2->name() : SyncName(); - if (localNode && localNode2 && (*localNode->id() == *localNode2->id() || localNode->isParentOf(localNode2))) { - LOGW_SYNCPAL_DEBUG(_logger, L"Removing " << syncOp2->type() << L" operation on " << SyncName2WStr(nodeName) - << L" because it depends on " << syncOp->type() << L" operation on " - << SyncName2WStr(localNode->name()) << L" wich failed."); - dependentOps.push_back(opId); - continue; - } - - if (remoteNode && remoteNode2 && (*remoteNode->id() == *remoteNode2->id() || remoteNode->isParentOf(remoteNode2))) { - LOGW_SYNCPAL_DEBUG(_logger, L"Removing " << syncOp2->type() << L" operation on " << SyncName2WStr(nodeName) - << L" because it depends on " << syncOp->type() << L" operation on " - << SyncName2WStr(nodeName) << L"wich failed."); - dependentOps.push_back(opId); - } - } - - for (const auto &opId: dependentOps) { - _opList.remove(opId); - } - for (const auto &opId: dependentOps) { - removeDependentOps(_syncPal->_syncOps->getOp(opId)); - } - if (!dependentOps.empty()) { - LOGW_SYNCPAL_DEBUG(_logger, L"Removed " << dependentOps.size() << L" dependent operations."); - _syncPal->setRestart(true); - } - - return ExitCode::Ok; -} - ExitInfo ExecutorWorker::handleCreateOp(SyncOpPtr syncOp, std::shared_ptr &job, bool &ignored) { // The execution of the create operation consists of three steps: // 1. If omit-flag is False, propagate the file or directory to target replica, because the object is missing there. @@ -2667,4 +2554,115 @@ ExitInfo ExecutorWorker::getFileSize(const SyncPath &path, uint64_t &size) { return ExitCode::Ok; } +ExitInfo ExecutorWorker::handleOpsExecutionError(SyncOpPtr syncOp, ExitInfo opsExitInfo) { + assert((syncOp && !opsExitInfo) && "syncOp is nullptr in ExecutorWorker::handleOpsExecutionError"); + if (!syncOp) { + LOG_WARN(_logger, "syncOp is nullptr in ExecutorWorker::handleOpsExecutionError"); + return ExitCode::DataError; + } + if (opsExitInfo) { + return opsExitInfo; + } + + // Handle specific errors + switch (static_cast(opsExitInfo)) { + case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::FileAccessError)): + case static_cast(ExitInfo(ExitCode::SystemError, ExitCause::MoveToTrashFailed)): { + return handleOpsFileAccessError(syncOp, opsExitInfo); + } + default: { + break; + } + }; + LOG_WARN(_logger, + "Unhandled error in ExecutorWorker::handleOpsExecutionError: " << opsExitInfo.code() << " " << opsExitInfo.cause()); + return opsExitInfo; +} + +ExitInfo ExecutorWorker::handleOpsFileAccessError(SyncOpPtr syncOp, ExitInfo opsExitInfo) { + if (syncOp->targetSide() == ReplicaSide::Local && syncOp->type() == OperationType::Create) { + // The item does not exist yet locally, we will only tmpBlacklist the remote item + _syncPal->handleAccessDeniedItem(syncOp->affectedNode()->getPath()); + } else { + // Both local and remote item will be temporarily blacklisted + auto localNode = syncOp->targetSide() == ReplicaSide::Remote ? syncOp->affectedNode() : syncOp->correspondingNode(); + if (!localNode) return ExitCode::LogicError; + SyncPath relativeLocalFilePath = localNode->getPath(); + SyncPath absoluteLocalFilePath = _syncPal->localPath() / relativeLocalFilePath; + NodeId localNodeId = localNode->id().has_value() ? *localNode->id() : NodeId(); + _syncPal->handleAccessDeniedItem(absoluteLocalFilePath, localNodeId, opsExitInfo.cause()); + _syncPal->blacklistTemporarily(syncOp->affectedNode()->id().has_value() ? *syncOp->affectedNode()->id() : std::string(), + syncOp->nodePath(ReplicaSide::Local), otherSide(syncOp->targetSide())); + Error error(_syncPal->syncDbId(), "", "", NodeType::Directory, + _syncPal->localPath() / syncOp->nodePath(ReplicaSide::Local), ConflictType::None, InconsistencyType::None, + CancelType::None, "", opsExitInfo.code(), opsExitInfo.cause()); + _syncPal->addError(error); + + if (!affectedUpdateTree(syncOp)->deleteNode(syncOp->affectedNode())) { + LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node name=" + << SyncName2WStr(syncOp->affectedNode()->name()).c_str()); + return ExitCode::DataError; + } + + if (syncOp->correspondingNode()) { + if (!targetUpdateTree(syncOp)->deleteNode(syncOp->correspondingNode())) { + LOGW_SYNCPAL_WARN(_logger, L"Error in UpdateTree::deleteNode: node name=" + << SyncName2WStr(syncOp->correspondingNode()->name()).c_str()); + return ExitCode::DataError; + } + } + } + + removeDependentOps(syncOp); + return ExitCode::Ok; +} + +ExitInfo ExecutorWorker::removeDependentOps(SyncOpPtr syncOp) { + auto localNode = syncOp->affectedNode()->side() == ReplicaSide::Local ? syncOp->affectedNode() : syncOp->correspondingNode(); + auto remoteNode = + syncOp->affectedNode()->side() == ReplicaSide::Remote ? syncOp->affectedNode() : syncOp->correspondingNode(); + + std::list dependentOps; + for (const auto &opId: _opList) { + SyncOpPtr syncOp2 = _syncPal->_syncOps->getOp(opId); + if (!syncOp2) { + LOGW_SYNCPAL_WARN(_logger, L"Operation doesn't exist anymore: id=" << opId); + continue; + } + auto localNode2 = + syncOp2->affectedNode()->side() == ReplicaSide::Local ? syncOp2->affectedNode() : syncOp2->correspondingNode(); + auto remoteNode2 = + syncOp2->affectedNode()->side() == ReplicaSide::Remote ? syncOp2->affectedNode() : syncOp2->correspondingNode(); + SyncName nodeName = localNode2 ? localNode2->name() : SyncName(); + nodeName = (nodeName.empty() && remoteNode2) ? remoteNode2->name() : SyncName(); + if (localNode && localNode2 && (*localNode->id() == *localNode2->id() || localNode->isParentOf(localNode2))) { + LOGW_SYNCPAL_DEBUG(_logger, L"Removing " << syncOp2->type() << L" operation on " << SyncName2WStr(nodeName) + << L" because it depends on " << syncOp->type() << L" operation on " + << SyncName2WStr(localNode->name()) << L" wich failed."); + dependentOps.push_back(opId); + continue; + } + + if (remoteNode && remoteNode2 && (*remoteNode->id() == *remoteNode2->id() || remoteNode->isParentOf(remoteNode2))) { + LOGW_SYNCPAL_DEBUG(_logger, L"Removing " << syncOp2->type() << L" operation on " << SyncName2WStr(nodeName) + << L" because it depends on " << syncOp->type() << L" operation on " + << SyncName2WStr(nodeName) << L"wich failed."); + dependentOps.push_back(opId); + } + } + + for (const auto &opId: dependentOps) { + _opList.remove(opId); + } + for (const auto &opId: dependentOps) { + removeDependentOps(_syncPal->_syncOps->getOp(opId)); + } + if (!dependentOps.empty()) { + LOGW_SYNCPAL_DEBUG(_logger, L"Removed " << dependentOps.size() << L" dependent operations."); + _syncPal->setRestart(true); + } + + return ExitCode::Ok; +} + } // namespace KDC