From ce93b9a1f4ea001587a0d8ecc39d4473326e1cf8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Feb 2018 16:48:37 -0800 Subject: [PATCH 1/6] Simplify BackupHandler pattern --- domain-server/src/BackupHandler.h | 64 +++---------------- domain-server/src/BackupSupervisor.h | 4 +- .../src/DomainContentBackupManager.cpp | 11 ++-- .../src/DomainContentBackupManager.h | 4 +- domain-server/src/DomainServer.cpp | 4 +- 5 files changed, 22 insertions(+), 65 deletions(-) diff --git a/domain-server/src/BackupHandler.h b/domain-server/src/BackupHandler.h index f2735e5adf..eb9c35f236 100644 --- a/domain-server/src/BackupHandler.h +++ b/domain-server/src/BackupHandler.h @@ -18,68 +18,22 @@ #include -class BackupHandler { +class BackupHandlerInterface { public: - template - BackupHandler(T* x) : _self(new Model(x)) {} + virtual ~BackupHandlerInterface() = default; - void loadBackup(QuaZip& zip) { - _self->loadBackup(zip); - } - void createBackup(QuaZip& zip) { - _self->createBackup(zip); - } - void recoverBackup(QuaZip& zip) { - _self->recoverBackup(zip); - } - void deleteBackup(QuaZip& zip) { - _self->deleteBackup(zip); - } - void consolidateBackup(QuaZip& zip) { - _self->consolidateBackup(zip); - } - -private: - struct Concept { - virtual ~Concept() = default; - - virtual void loadBackup(QuaZip& zip) = 0; - virtual void createBackup(QuaZip& zip) = 0; - virtual void recoverBackup(QuaZip& zip) = 0; - virtual void deleteBackup(QuaZip& zip) = 0; - virtual void consolidateBackup(QuaZip& zip) = 0; - }; - - template - struct Model : Concept { - Model(T* x) : data(x) {} - - void loadBackup(QuaZip& zip) override { - data->loadBackup(zip); - } - void createBackup(QuaZip& zip) override { - data->createBackup(zip); - } - void recoverBackup(QuaZip& zip) override { - data->recoverBackup(zip); - } - void deleteBackup(QuaZip& zip) override { - data->deleteBackup(zip); - } - void consolidateBackup(QuaZip& zip) override { - data->consolidateBackup(zip); - } - - std::unique_ptr data; - }; - - std::unique_ptr _self; + virtual void loadBackup(QuaZip& zip) = 0; + virtual void createBackup(QuaZip& zip) = 0; + virtual void recoverBackup(QuaZip& zip) = 0; + virtual void deleteBackup(QuaZip& zip) = 0; + virtual void consolidateBackup(QuaZip& zip) = 0; }; +using BackupHandlerPointer = std::unique_ptr; #include #include -class EntitiesBackupHandler { +class EntitiesBackupHandler : public BackupHandlerInterface { public: EntitiesBackupHandler(QString entitiesFilePath, QString entitiesReplacementFilePath) : _entitiesFilePath(entitiesFilePath), diff --git a/domain-server/src/BackupSupervisor.h b/domain-server/src/BackupSupervisor.h index 9fedcca19b..0d0d21a174 100644 --- a/domain-server/src/BackupSupervisor.h +++ b/domain-server/src/BackupSupervisor.h @@ -24,6 +24,8 @@ #include +#include "BackupHandler.h" + class QuaZip; struct AssetServerBackup { @@ -32,7 +34,7 @@ struct AssetServerBackup { bool corruptedBackup; }; -class BackupSupervisor : public QObject { +class BackupSupervisor : public QObject, public BackupHandlerInterface { Q_OBJECT public: diff --git a/domain-server/src/DomainContentBackupManager.cpp b/domain-server/src/DomainContentBackupManager.cpp index 66655ea966..2b990b170e 100644 --- a/domain-server/src/DomainContentBackupManager.cpp +++ b/domain-server/src/DomainContentBackupManager.cpp @@ -39,7 +39,8 @@ static const QString DATETIME_FORMAT { "yyyy-MM-dd_HH-mm-ss" }; static const QString DATETIME_FORMAT_RE { "\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}" }; static const QString AUTOMATIC_BACKUP_PREFIX { "autobackup-" }; static const QString MANUAL_BACKUP_PREFIX { "backup-" }; -void DomainContentBackupManager::addBackupHandler(BackupHandler handler) { + +void DomainContentBackupManager::addBackupHandler(BackupHandlerPointer handler) { _backupHandlers.push_back(std::move(handler)); } @@ -238,7 +239,7 @@ void DomainContentBackupManager::recoverFromBackup(MiniPromise::Promise promise, success = false; } else { for (auto& handler : _backupHandlers) { - handler.recoverBackup(zip); + handler->recoverBackup(zip); } qDebug() << "Successfully recovered from " << backupName; @@ -339,7 +340,7 @@ void DomainContentBackupManager::load() { } for (auto& handler : _backupHandlers) { - handler.loadBackup(zip); + handler->loadBackup(zip); } zip.close(); @@ -402,7 +403,7 @@ void DomainContentBackupManager::consolidate(QString fileName) { } for (auto& handler : _backupHandlers) { - handler.consolidateBackup(zip); + handler->consolidateBackup(zip); } zip.close(); @@ -437,7 +438,7 @@ std::pair DomainContentBackupManager::createBackup(const QString& } for (auto& handler : _backupHandlers) { - handler.createBackup(zip); + handler->createBackup(zip); } zip.close(); diff --git a/domain-server/src/DomainContentBackupManager.h b/domain-server/src/DomainContentBackupManager.h index 5cf8d4698f..a3606929d5 100644 --- a/domain-server/src/DomainContentBackupManager.h +++ b/domain-server/src/DomainContentBackupManager.h @@ -50,7 +50,7 @@ public: int persistInterval = DEFAULT_PERSIST_INTERVAL, bool debugTimestampNow = false); - void addBackupHandler(BackupHandler handler); + void addBackupHandler(BackupHandlerPointer handler); std::vector getAllBackups(); void aboutToFinish(); /// call this to inform the persist thread that the owner is about to finish to support final persist @@ -82,7 +82,7 @@ protected: private: const QString _backupDirectory; - std::vector _backupHandlers; + std::vector _backupHandlers; int _persistInterval { 0 }; int64_t _lastCheck { 0 }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index da8527bf16..a8ceebd6e7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -296,8 +296,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : maybeHandleReplacementEntityFile(); _contentManager.reset(new DomainContentBackupManager(getContentBackupDir(), _settingsManager.settingsResponseObjectForType("6")["entity_server_settings"].toObject())); - _contentManager->addBackupHandler(new EntitiesBackupHandler(getEntitiesFilePath(), getEntitiesReplacementFilePath())); - _contentManager->addBackupHandler(new BackupSupervisor(getContentBackupDir())); + _contentManager->addBackupHandler(BackupHandlerPointer(new EntitiesBackupHandler(getEntitiesFilePath(), getEntitiesReplacementFilePath()))); + _contentManager->addBackupHandler(BackupHandlerPointer(new BackupSupervisor(getContentBackupDir()))); _contentManager->initialize(true); qDebug() << "Existing backups:"; From 4482f9c83c67def4fef5444a52f6d85e531ce53f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Feb 2018 16:49:12 -0800 Subject: [PATCH 2/6] Queue all requests until the AS is fully setup --- assignment-client/src/assets/AssetServer.cpp | 45 +++++++++++++++++--- assignment-client/src/assets/AssetServer.h | 5 +++ domain-server/src/BackupSupervisor.cpp | 5 +-- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 1ae65290ff..0be557bccd 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -257,12 +257,10 @@ AssetServer::AssetServer(ReceivedMessage& message) : _transferTaskPool.setMaxThreadCount(TASK_POOL_THREAD_COUNT); _bakingTaskPool.setMaxThreadCount(1); + // Queue all requests until the Asset Server is fully setup auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet"); - packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo"); - packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload"); - packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation"); - + packetReceiver.registerListenerForTypes({ PacketType::AssetGet, PacketType::AssetGetInfo, PacketType::AssetUpload, PacketType::AssetMappingOperation }, this, "queueRequests"); + #ifdef Q_OS_WIN updateConsumedCores(); QTimer* timer = new QTimer(this); @@ -417,6 +415,43 @@ void AssetServer::completeSetup() { PathUtils::removeTemporaryApplicationDirs(); PathUtils::removeTemporaryApplicationDirs("Oven"); + + // We're fully setup, remove the request queueing and replay all requests + auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); + packetReceiver.unregisterListener(this); + packetReceiver.registerListener(PacketType::AssetGet, this, "handleAssetGet"); + packetReceiver.registerListener(PacketType::AssetGetInfo, this, "handleAssetGetInfo"); + packetReceiver.registerListener(PacketType::AssetUpload, this, "handleAssetUpload"); + packetReceiver.registerListener(PacketType::AssetMappingOperation, this, "handleAssetMappingOperation"); + + replayRequests(); +} + +void AssetServer::queueRequests(QSharedPointer packet, SharedNodePointer senderNode) { + _queuedRequests.push_back({ packet, senderNode }); +} + +void AssetServer::replayRequests() { + for (const auto& request : _queuedRequests) { + switch (request.first->getType()) { + case PacketType::AssetGet: + handleAssetGet(request.first, request.second); + break; + case PacketType::AssetGetInfo: + handleAssetGetInfo(request.first, request.second); + break; + case PacketType::AssetUpload: + handleAssetUpload(request.first, request.second); + break; + case PacketType::AssetMappingOperation: + handleAssetMappingOperation(request.first, request.second); + break; + default: + qWarning() << "Unknown queued request type:" << request.first->getType(); + break; + } + } + _queuedRequests.clear(); } void AssetServer::cleanupUnmappedFiles() { diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index c6336a3a4d..b8aac800ed 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -49,6 +49,7 @@ public slots: private slots: void completeSetup(); + void queueRequests(QSharedPointer packet, SharedNodePointer senderNode); void handleAssetGetInfo(QSharedPointer packet, SharedNodePointer senderNode); void handleAssetGet(QSharedPointer packet, SharedNodePointer senderNode); void handleAssetUpload(QSharedPointer packetList, SharedNodePointer senderNode); @@ -57,6 +58,8 @@ private slots: void sendStatsPacket() override; private: + void replayRequests(); + void handleGetMappingOperation(ReceivedMessage& message, NLPacketList& replyPacket); void handleGetAllMappingOperation(NLPacketList& replyPacket); void handleSetMappingOperation(ReceivedMessage& message, bool hasWriteAccess, NLPacketList& replyPacket); @@ -120,6 +123,8 @@ private: QHash> _pendingBakes; QThreadPool _bakingTaskPool; + QVector, SharedNodePointer>> _queuedRequests; + bool _wasColorTextureCompressionEnabled { false }; bool _wasGrayscaleTextureCompressionEnabled { false }; bool _wasNormalTextureCompressionEnabled { false }; diff --git a/domain-server/src/BackupSupervisor.cpp b/domain-server/src/BackupSupervisor.cpp index 869f85c6cc..0cbded4e43 100644 --- a/domain-server/src/BackupSupervisor.cpp +++ b/domain-server/src/BackupSupervisor.cpp @@ -46,9 +46,8 @@ BackupSupervisor::BackupSupervisor(const QString& backupDirectory) : auto nodeList = DependencyManager::get(); QObject::connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, [this](SharedNodePointer node) { if (node->getType() == NodeType::AssetServer) { - // Give the Asset Server some time to bootup. - static constexpr int ASSET_SERVER_BOOTUP_MARGIN = 1 * 1000; - _mappingsRefreshTimer.start(ASSET_SERVER_BOOTUP_MARGIN); + // run immediately for the first time. + _mappingsRefreshTimer.start(0); } }); } From d8d05fe0456831cd9dadde546c3635f09eafa46c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Feb 2018 17:24:00 -0800 Subject: [PATCH 3/6] Rename backup supervisor --- ...Supervisor.cpp => AssetsBackupHandler.cpp} | 42 +++++++++---------- ...ckupSupervisor.h => AssetsBackupHandler.h} | 24 +++++------ domain-server/src/DomainServer.cpp | 4 +- domain-server/src/DomainServer.h | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-) rename domain-server/src/{BackupSupervisor.cpp => AssetsBackupHandler.cpp} (93%) rename domain-server/src/{BackupSupervisor.h => AssetsBackupHandler.h} (85%) diff --git a/domain-server/src/BackupSupervisor.cpp b/domain-server/src/AssetsBackupHandler.cpp similarity index 93% rename from domain-server/src/BackupSupervisor.cpp rename to domain-server/src/AssetsBackupHandler.cpp index 0cbded4e43..3dc4851762 100644 --- a/domain-server/src/BackupSupervisor.cpp +++ b/domain-server/src/AssetsBackupHandler.cpp @@ -1,5 +1,5 @@ // -// BackupSupervisor.cpp +// AssetsBackupHandler.cpp // domain-server/src // // Created by Clement Brisset on 1/12/18. @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "BackupSupervisor.h" +#include "AssetsBackupHandler.h" #include #include @@ -31,7 +31,7 @@ using namespace std; Q_DECLARE_LOGGING_CATEGORY(backup_supervisor) Q_LOGGING_CATEGORY(backup_supervisor, "hifi.backup-supervisor"); -BackupSupervisor::BackupSupervisor(const QString& backupDirectory) : +AssetsBackupHandler::AssetsBackupHandler(const QString& backupDirectory) : _assetsDirectory(backupDirectory + ASSETS_DIR) { // Make sure the asset directory exists. @@ -41,7 +41,7 @@ BackupSupervisor::BackupSupervisor(const QString& backupDirectory) : _mappingsRefreshTimer.setTimerType(Qt::CoarseTimer); _mappingsRefreshTimer.setSingleShot(true); - QObject::connect(&_mappingsRefreshTimer, &QTimer::timeout, this, &BackupSupervisor::refreshMappings); + QObject::connect(&_mappingsRefreshTimer, &QTimer::timeout, this, &AssetsBackupHandler::refreshMappings); auto nodeList = DependencyManager::get(); QObject::connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, [this](SharedNodePointer node) { @@ -53,7 +53,7 @@ BackupSupervisor::BackupSupervisor(const QString& backupDirectory) : } -void BackupSupervisor::refreshAssetsOnDisk() { +void AssetsBackupHandler::refreshAssetsOnDisk() { QDir assetsDir { _assetsDirectory }; auto assetNames = assetsDir.entryList(QDir::Files); @@ -64,7 +64,7 @@ void BackupSupervisor::refreshAssetsOnDisk() { } -void BackupSupervisor::refreshAssetsInBackups() { +void AssetsBackupHandler::refreshAssetsInBackups() { _assetsInBackups.clear(); for (const auto& backup : _backups) { for (const auto& mapping : backup.mappings) { @@ -73,7 +73,7 @@ void BackupSupervisor::refreshAssetsInBackups() { } } -void BackupSupervisor::checkForMissingAssets() { +void AssetsBackupHandler::checkForMissingAssets() { vector missingAssets; set_difference(begin(_assetsInBackups), end(_assetsInBackups), begin(_assetsOnDisk), end(_assetsOnDisk), @@ -83,7 +83,7 @@ void BackupSupervisor::checkForMissingAssets() { } } -void BackupSupervisor::checkForAssetsToDelete() { +void AssetsBackupHandler::checkForAssetsToDelete() { vector deprecatedAssets; set_difference(begin(_assetsOnDisk), end(_assetsOnDisk), begin(_assetsInBackups), end(_assetsInBackups), @@ -101,7 +101,7 @@ void BackupSupervisor::checkForAssetsToDelete() { } } -void BackupSupervisor::loadBackup(QuaZip& zip) { +void AssetsBackupHandler::loadBackup(QuaZip& zip) { _backups.push_back({ zip.getZipName(), {}, false }); auto& backup = _backups.back(); @@ -151,7 +151,7 @@ void BackupSupervisor::loadBackup(QuaZip& zip) { return; } -void BackupSupervisor::createBackup(QuaZip& zip) { +void AssetsBackupHandler::createBackup(QuaZip& zip) { if (operationInProgress()) { qCWarning(backup_supervisor) << "There is already an operation in progress."; return; @@ -192,7 +192,7 @@ void BackupSupervisor::createBackup(QuaZip& zip) { _backups.push_back(backup); } -void BackupSupervisor::recoverBackup(QuaZip& zip) { +void AssetsBackupHandler::recoverBackup(QuaZip& zip) { if (operationInProgress()) { qCWarning(backup_supervisor) << "There is already a backup/restore in progress."; return; @@ -225,7 +225,7 @@ void BackupSupervisor::recoverBackup(QuaZip& zip) { restoreAllAssets(); } -void BackupSupervisor::deleteBackup(QuaZip& zip) { +void AssetsBackupHandler::deleteBackup(QuaZip& zip) { if (operationInProgress()) { qCWarning(backup_supervisor) << "There is a backup/restore in progress."; return; @@ -243,7 +243,7 @@ void BackupSupervisor::deleteBackup(QuaZip& zip) { checkForAssetsToDelete(); } -void BackupSupervisor::consolidateBackup(QuaZip& zip) { +void AssetsBackupHandler::consolidateBackup(QuaZip& zip) { if (operationInProgress()) { qCWarning(backup_supervisor) << "There is a backup/restore in progress."; return; @@ -285,7 +285,7 @@ void BackupSupervisor::consolidateBackup(QuaZip& zip) { } -void BackupSupervisor::refreshMappings() { +void AssetsBackupHandler::refreshMappings() { auto assetClient = DependencyManager::get(); auto request = assetClient->createGetAllMappingsRequest(); @@ -314,7 +314,7 @@ void BackupSupervisor::refreshMappings() { request->start(); } -void BackupSupervisor::downloadMissingFiles(const AssetUtils::Mappings& mappings) { +void AssetsBackupHandler::downloadMissingFiles(const AssetUtils::Mappings& mappings) { auto wasEmpty = _assetsLeftToRequest.empty(); for (const auto& mapping : mappings) { @@ -330,7 +330,7 @@ void BackupSupervisor::downloadMissingFiles(const AssetUtils::Mappings& mappings } } -void BackupSupervisor::downloadNextMissingFile() { +void AssetsBackupHandler::downloadNextMissingFile() { if (_assetsLeftToRequest.empty()) { return; } @@ -360,7 +360,7 @@ void BackupSupervisor::downloadNextMissingFile() { assetRequest->start(); } -bool BackupSupervisor::writeAssetFile(const AssetUtils::AssetHash& hash, const QByteArray& data) { +bool AssetsBackupHandler::writeAssetFile(const AssetUtils::AssetHash& hash, const QByteArray& data) { QDir assetsDir { _assetsDirectory }; QFile file { assetsDir.filePath(hash) }; if (!file.open(QFile::WriteOnly)) { @@ -380,7 +380,7 @@ bool BackupSupervisor::writeAssetFile(const AssetUtils::AssetHash& hash, const Q return true; } -void BackupSupervisor::computeServerStateDifference(const AssetUtils::Mappings& currentMappings, +void AssetsBackupHandler::computeServerStateDifference(const AssetUtils::Mappings& currentMappings, const AssetUtils::Mappings& newMappings) { _mappingsLeftToSet.reserve((int)newMappings.size()); _assetsLeftToUpload.reserve((int)newMappings.size()); @@ -415,11 +415,11 @@ void BackupSupervisor::computeServerStateDifference(const AssetUtils::Mappings& qCDebug(backup_supervisor) << "Assets to upload:" << _assetsLeftToUpload.size(); } -void BackupSupervisor::restoreAllAssets() { +void AssetsBackupHandler::restoreAllAssets() { restoreNextAsset(); } -void BackupSupervisor::restoreNextAsset() { +void AssetsBackupHandler::restoreNextAsset() { if (_assetsLeftToUpload.empty()) { updateMappings(); return; @@ -447,7 +447,7 @@ void BackupSupervisor::restoreNextAsset() { request->start(); } -void BackupSupervisor::updateMappings() { +void AssetsBackupHandler::updateMappings() { auto assetClient = DependencyManager::get(); for (const auto& mapping : _mappingsLeftToSet) { auto request = assetClient->createSetMappingRequest(mapping.first, mapping.second); diff --git a/domain-server/src/BackupSupervisor.h b/domain-server/src/AssetsBackupHandler.h similarity index 85% rename from domain-server/src/BackupSupervisor.h rename to domain-server/src/AssetsBackupHandler.h index 0d0d21a174..184f30ab9b 100644 --- a/domain-server/src/BackupSupervisor.h +++ b/domain-server/src/AssetsBackupHandler.h @@ -1,5 +1,5 @@ // -// BackupSupervisor.h +// AssetsBackupHandler.h // domain-server/src // // Created by Clement Brisset on 1/12/18. @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_BackupSupervisor_h -#define hifi_BackupSupervisor_h +#ifndef hifi_AssetsBackupHandler_h +#define hifi_AssetsBackupHandler_h #include #include @@ -28,17 +28,11 @@ class QuaZip; -struct AssetServerBackup { - QString filePath; - AssetUtils::Mappings mappings; - bool corruptedBackup; -}; - -class BackupSupervisor : public QObject, public BackupHandlerInterface { +class AssetsBackupHandler : public QObject, public BackupHandlerInterface { Q_OBJECT public: - BackupSupervisor(const QString& backupDirectory); + AssetsBackupHandler(const QString& backupDirectory); void loadBackup(QuaZip& zip); void createBackup(QuaZip& zip); @@ -75,6 +69,12 @@ private: quint64 _lastMappingsRefresh { 0 }; AssetUtils::Mappings _currentMappings; + struct AssetServerBackup { + QString filePath; + AssetUtils::Mappings mappings; + bool corruptedBackup; + }; + bool _operationInProgress { false }; // Internal storage for backups on disk @@ -93,4 +93,4 @@ private: int _mappingRequestsInFlight { 0 }; }; -#endif /* hifi_BackupSupervisor_h */ +#endif /* hifi_AssetsBackupHandler_h */ diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index a8ceebd6e7..11b6a2d441 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -45,7 +45,7 @@ #include #include -#include "BackupSupervisor.h" +#include "AssetsBackupHandler.h" #include "DomainServerNodeData.h" #include "NodeConnectionData.h" @@ -297,7 +297,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : _contentManager.reset(new DomainContentBackupManager(getContentBackupDir(), _settingsManager.settingsResponseObjectForType("6")["entity_server_settings"].toObject())); _contentManager->addBackupHandler(BackupHandlerPointer(new EntitiesBackupHandler(getEntitiesFilePath(), getEntitiesReplacementFilePath()))); - _contentManager->addBackupHandler(BackupHandlerPointer(new BackupSupervisor(getContentBackupDir()))); + _contentManager->addBackupHandler(BackupHandlerPointer(new AssetsBackupHandler(getContentBackupDir()))); _contentManager->initialize(true); qDebug() << "Existing backups:"; diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index ee0350665e..afe2a1cc7c 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -26,7 +26,7 @@ #include #include -#include "BackupSupervisor.h" +#include "AssetsBackupHandler.h" #include "DomainGatekeeper.h" #include "DomainMetadata.h" #include "DomainServerSettingsManager.h" From 9fca92facd27f12a0daff1455b0dc560fda4db46 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 Feb 2018 18:11:55 -0800 Subject: [PATCH 4/6] Move EntitiesBackupHandler to its own file --- domain-server/src/AssetsBackupHandler.h | 3 - domain-server/src/BackupHandler.h | 79 +------------------ .../src/DomainContentBackupManager.cpp | 6 +- .../src/DomainContentBackupManager.h | 1 + domain-server/src/DomainServer.cpp | 1 + domain-server/src/EntitiesBackupHandler.cpp | 73 +++++++++++++++++ domain-server/src/EntitiesBackupHandler.h | 42 ++++++++++ 7 files changed, 124 insertions(+), 81 deletions(-) create mode 100644 domain-server/src/EntitiesBackupHandler.cpp create mode 100644 domain-server/src/EntitiesBackupHandler.h diff --git a/domain-server/src/AssetsBackupHandler.h b/domain-server/src/AssetsBackupHandler.h index 184f30ab9b..b78206b7b1 100644 --- a/domain-server/src/AssetsBackupHandler.h +++ b/domain-server/src/AssetsBackupHandler.h @@ -21,13 +21,10 @@ #include #include - #include #include "BackupHandler.h" -class QuaZip; - class AssetsBackupHandler : public QObject, public BackupHandlerInterface { Q_OBJECT diff --git a/domain-server/src/BackupHandler.h b/domain-server/src/BackupHandler.h index eb9c35f236..8599dafb29 100644 --- a/domain-server/src/BackupHandler.h +++ b/domain-server/src/BackupHandler.h @@ -14,9 +14,7 @@ #include -#include - -#include +class QuaZip; class BackupHandlerInterface { public: @@ -28,80 +26,7 @@ public: virtual void deleteBackup(QuaZip& zip) = 0; virtual void consolidateBackup(QuaZip& zip) = 0; }; + using BackupHandlerPointer = std::unique_ptr; -#include -#include - -class EntitiesBackupHandler : public BackupHandlerInterface { -public: - EntitiesBackupHandler(QString entitiesFilePath, QString entitiesReplacementFilePath) : - _entitiesFilePath(entitiesFilePath), - _entitiesReplacementFilePath(entitiesReplacementFilePath) {} - - void loadBackup(QuaZip& zip) {} - - // Create a skeleton backup - void createBackup(QuaZip& zip) { - QFile entitiesFile { _entitiesFilePath }; - - if (entitiesFile.open(QIODevice::ReadOnly)) { - QuaZipFile zipFile { &zip }; - zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("models.json.gz", _entitiesFilePath)); - zipFile.write(entitiesFile.readAll()); - zipFile.close(); - if (zipFile.getZipError() != UNZ_OK) { - qCritical() << "Failed to zip models.json.gz: " << zipFile.getZipError(); - } - } - } - - // Recover from a full backup - void recoverBackup(QuaZip& zip) { - if (!zip.setCurrentFile("models.json.gz")) { - qWarning() << "Failed to find models.json.gz while recovering backup"; - return; - } - QuaZipFile zipFile { &zip }; - if (!zipFile.open(QIODevice::ReadOnly)) { - qCritical() << "Failed to open models.json.gz in backup"; - return; - } - auto rawData = zipFile.readAll(); - - zipFile.close(); - - OctreeUtils::RawOctreeData data; - if (!OctreeUtils::readOctreeDataInfoFromData(rawData, &data)) { - qCritical() << "Unable to parse octree data during backup recovery"; - return; - } - - data.resetIdAndVersion(); - - if (zipFile.getZipError() != UNZ_OK) { - qCritical() << "Failed to unzip models.json.gz: " << zipFile.getZipError(); - return; - } - - QFile entitiesFile { _entitiesReplacementFilePath }; - - if (entitiesFile.open(QIODevice::WriteOnly)) { - entitiesFile.write(data.toGzippedByteArray()); - } - } - - // Delete a skeleton backup - void deleteBackup(QuaZip& zip) { - } - - // Create a full backup - void consolidateBackup(QuaZip& zip) { - } - -private: - QString _entitiesFilePath; - QString _entitiesReplacementFilePath; -}; - #endif /* hifi_BackupHandler_h */ diff --git a/domain-server/src/DomainContentBackupManager.cpp b/domain-server/src/DomainContentBackupManager.cpp index 2b990b170e..f39737c92e 100644 --- a/domain-server/src/DomainContentBackupManager.cpp +++ b/domain-server/src/DomainContentBackupManager.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include "DomainContentBackupManager.h" + #include #include @@ -25,13 +27,15 @@ #include #include +#include + #include #include #include #include #include "DomainServer.h" -#include "DomainContentBackupManager.h" + const int DomainContentBackupManager::DEFAULT_PERSIST_INTERVAL = 1000 * 30; // every 30 seconds // Backup format looks like: daily_backup-TIMESTAMP.zip diff --git a/domain-server/src/DomainContentBackupManager.h b/domain-server/src/DomainContentBackupManager.h index a3606929d5..1e1b2360a8 100644 --- a/domain-server/src/DomainContentBackupManager.h +++ b/domain-server/src/DomainContentBackupManager.h @@ -16,6 +16,7 @@ #include #include +#include #include diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 11b6a2d441..4c72423f74 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -47,6 +47,7 @@ #include "AssetsBackupHandler.h" #include "DomainServerNodeData.h" +#include "EntitiesBackupHandler.h" #include "NodeConnectionData.h" #include diff --git a/domain-server/src/EntitiesBackupHandler.cpp b/domain-server/src/EntitiesBackupHandler.cpp new file mode 100644 index 0000000000..a95d68b007 --- /dev/null +++ b/domain-server/src/EntitiesBackupHandler.cpp @@ -0,0 +1,73 @@ +// +// EntitiesBackupHandler.cpp +// domain-server/src +// +// Created by Clement Brisset on 2/14/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "EntitiesBackupHandler.h" + +#include + +#include +#include + +#include + +EntitiesBackupHandler::EntitiesBackupHandler(QString entitiesFilePath, QString entitiesReplacementFilePath) : + _entitiesFilePath(entitiesFilePath), + _entitiesReplacementFilePath(entitiesReplacementFilePath) +{ +} + +void EntitiesBackupHandler::createBackup(QuaZip& zip) { + QFile entitiesFile { _entitiesFilePath }; + + if (entitiesFile.open(QIODevice::ReadOnly)) { + QuaZipFile zipFile { &zip }; + zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo("models.json.gz", _entitiesFilePath)); + zipFile.write(entitiesFile.readAll()); + zipFile.close(); + if (zipFile.getZipError() != UNZ_OK) { + qCritical() << "Failed to zip models.json.gz: " << zipFile.getZipError(); + } + } +} + +void EntitiesBackupHandler::recoverBackup(QuaZip& zip) { + if (!zip.setCurrentFile("models.json.gz")) { + qWarning() << "Failed to find models.json.gz while recovering backup"; + return; + } + QuaZipFile zipFile { &zip }; + if (!zipFile.open(QIODevice::ReadOnly)) { + qCritical() << "Failed to open models.json.gz in backup"; + return; + } + auto rawData = zipFile.readAll(); + + zipFile.close(); + + OctreeUtils::RawOctreeData data; + if (!OctreeUtils::readOctreeDataInfoFromData(rawData, &data)) { + qCritical() << "Unable to parse octree data during backup recovery"; + return; + } + + data.resetIdAndVersion(); + + if (zipFile.getZipError() != UNZ_OK) { + qCritical() << "Failed to unzip models.json.gz: " << zipFile.getZipError(); + return; + } + + QFile entitiesFile { _entitiesReplacementFilePath }; + + if (entitiesFile.open(QIODevice::WriteOnly)) { + entitiesFile.write(data.toGzippedByteArray()); + } +} diff --git a/domain-server/src/EntitiesBackupHandler.h b/domain-server/src/EntitiesBackupHandler.h new file mode 100644 index 0000000000..6f66483a87 --- /dev/null +++ b/domain-server/src/EntitiesBackupHandler.h @@ -0,0 +1,42 @@ +// +// EntitiesBackupHandler.h +// domain-server/src +// +// Created by Clement Brisset on 2/14/18. +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_EntitiesBackupHandler_h +#define hifi_EntitiesBackupHandler_h + +#include + +#include "BackupHandler.h" + +class EntitiesBackupHandler : public BackupHandlerInterface { +public: + EntitiesBackupHandler(QString entitiesFilePath, QString entitiesReplacementFilePath); + + void loadBackup(QuaZip& zip) {} + + // Create a skeleton backup + void createBackup(QuaZip& zip); + + // Recover from a full backup + void recoverBackup(QuaZip& zip); + + // Delete a skeleton backup + void deleteBackup(QuaZip& zip) {} + + // Create a full backup + void consolidateBackup(QuaZip& zip) {} + +private: + QString _entitiesFilePath; + QString _entitiesReplacementFilePath; +}; + +#endif /* hifi_EntitiesBackupHandler_h */ From d6e281408144f0db5bb102ca4a0b99dd460cd63f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 15 Feb 2018 11:25:07 -0800 Subject: [PATCH 5/6] Write assets to disk when recovering full backup --- domain-server/src/AssetsBackupHandler.cpp | 152 ++++++++++++++-------- domain-server/src/AssetsBackupHandler.h | 1 + 2 files changed, 99 insertions(+), 54 deletions(-) diff --git a/domain-server/src/AssetsBackupHandler.cpp b/domain-server/src/AssetsBackupHandler.cpp index 3dc4851762..a9f56a0c5b 100644 --- a/domain-server/src/AssetsBackupHandler.cpp +++ b/domain-server/src/AssetsBackupHandler.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -23,13 +24,14 @@ #include #include -const QString ASSETS_DIR = "/assets/"; -const QString MAPPINGS_FILE = "mappings.json"; +static const QString ASSETS_DIR = "/assets/"; +static const QString MAPPINGS_FILE = "mappings.json"; +static const QString ZIP_ASSETS_FOLDER = "files"; using namespace std; -Q_DECLARE_LOGGING_CATEGORY(backup_supervisor) -Q_LOGGING_CATEGORY(backup_supervisor, "hifi.backup-supervisor"); +Q_DECLARE_LOGGING_CATEGORY(asset_backup) +Q_LOGGING_CATEGORY(asset_backup, "hifi.asset-backup"); AssetsBackupHandler::AssetsBackupHandler(const QString& backupDirectory) : _assetsDirectory(backupDirectory + ASSETS_DIR) @@ -39,6 +41,10 @@ AssetsBackupHandler::AssetsBackupHandler(const QString& backupDirectory) : refreshAssetsOnDisk(); + setupRefreshTimer(); +} + +void AssetsBackupHandler::setupRefreshTimer() { _mappingsRefreshTimer.setTimerType(Qt::CoarseTimer); _mappingsRefreshTimer.setSingleShot(true); QObject::connect(&_mappingsRefreshTimer, &QTimer::timeout, this, &AssetsBackupHandler::refreshMappings); @@ -50,9 +56,14 @@ AssetsBackupHandler::AssetsBackupHandler(const QString& backupDirectory) : _mappingsRefreshTimer.start(0); } }); + QObject::connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, [this](SharedNodePointer node) { + if (node->getType() == NodeType::AssetServer) { + // run immediately for the first time. + _mappingsRefreshTimer.stop(); + } + }); } - void AssetsBackupHandler::refreshAssetsOnDisk() { QDir assetsDir { _assetsDirectory }; auto assetNames = assetsDir.entryList(QDir::Files); @@ -79,7 +90,7 @@ void AssetsBackupHandler::checkForMissingAssets() { begin(_assetsOnDisk), end(_assetsOnDisk), back_inserter(missingAssets)); if (missingAssets.size() > 0) { - qCWarning(backup_supervisor) << "Found" << missingAssets.size() << "assets missing."; + qCWarning(asset_backup) << "Found" << missingAssets.size() << "backup assets missing from disk."; } } @@ -90,24 +101,26 @@ void AssetsBackupHandler::checkForAssetsToDelete() { back_inserter(deprecatedAssets)); if (deprecatedAssets.size() > 0) { - qCDebug(backup_supervisor) << "Found" << deprecatedAssets.size() << "assets to delete."; + qCDebug(asset_backup) << "Found" << deprecatedAssets.size() << "backup assets to delete from disk."; if (_allBackupsLoadedSuccessfully) { for (const auto& hash : deprecatedAssets) { QFile::remove(_assetsDirectory + hash); } } else { - qCWarning(backup_supervisor) << "Some backups did not load properly, aborting deleting for safety."; + qCWarning(asset_backup) << "Some backups did not load properly, aborting delete operation for safety."; } } } void AssetsBackupHandler::loadBackup(QuaZip& zip) { + Q_ASSERT(QThread::currentThread() == thread()); + _backups.push_back({ zip.getZipName(), {}, false }); auto& backup = _backups.back(); if (!zip.setCurrentFile(MAPPINGS_FILE)) { - qCCritical(backup_supervisor) << "Failed to find" << MAPPINGS_FILE << "while recovering backup"; - qCCritical(backup_supervisor) << " Error:" << zip.getZipError(); + qCCritical(asset_backup) << "Failed to find" << MAPPINGS_FILE << "while loading backup"; + qCCritical(asset_backup) << " Error:" << zip.getZipError(); backup.corruptedBackup = true; _allBackupsLoadedSuccessfully = false; return; @@ -115,8 +128,8 @@ void AssetsBackupHandler::loadBackup(QuaZip& zip) { QuaZipFile zipFile { &zip }; if (!zipFile.open(QFile::ReadOnly)) { - qCCritical(backup_supervisor) << "Could not open backup file:" << zip.getZipName(); - qCCritical(backup_supervisor) << " Error:" << zip.getZipError(); + qCCritical(asset_backup) << "Could not unzip backup file for load:" << zip.getZipName(); + qCCritical(asset_backup) << " Error:" << zip.getZipError(); backup.corruptedBackup = true; _allBackupsLoadedSuccessfully = false; return; @@ -125,8 +138,8 @@ void AssetsBackupHandler::loadBackup(QuaZip& zip) { QJsonParseError error; auto document = QJsonDocument::fromJson(zipFile.readAll(), &error); if (document.isNull() || !document.isObject()) { - qCCritical(backup_supervisor) << "Could not parse backup file to JSON object:" << zip.getZipName(); - qCCritical(backup_supervisor) << " Error:" << error.errorString(); + qCCritical(asset_backup) << "Could not parse backup file to JSON object for load:" << zip.getZipName(); + qCCritical(asset_backup) << " Error:" << error.errorString(); backup.corruptedBackup = true; _allBackupsLoadedSuccessfully = false; return; @@ -138,33 +151,37 @@ void AssetsBackupHandler::loadBackup(QuaZip& zip) { const auto& assetHash = it.value().toString(); if (!AssetUtils::isValidHash(assetHash)) { - qCCritical(backup_supervisor) << "Corrupted mapping in backup file" << zip.getZipName() << ":" << it.key(); + qCCritical(asset_backup) << "Corrupted mapping in loading backup file" << zip.getZipName() << ":" << it.key(); backup.corruptedBackup = true; _allBackupsLoadedSuccessfully = false; - return; + continue; } backup.mappings[assetPath] = assetHash; _assetsInBackups.insert(assetHash); } + checkForMissingAssets(); + checkForAssetsToDelete(); return; } void AssetsBackupHandler::createBackup(QuaZip& zip) { + Q_ASSERT(QThread::currentThread() == thread()); + if (operationInProgress()) { - qCWarning(backup_supervisor) << "There is already an operation in progress."; + qCWarning(asset_backup) << "There is already an operation in progress."; return; } if (_lastMappingsRefresh == 0) { - qCWarning(backup_supervisor) << "Current mappings not yet loaded."; + qCWarning(asset_backup) << "Current mappings not yet loaded."; return; } static constexpr quint64 MAX_REFRESH_TIME = 15 * 60 * 1000 * 1000; if (usecTimestampNow() - _lastMappingsRefresh > MAX_REFRESH_TIME) { - qCWarning(backup_supervisor) << "Backing up asset mappings that might be stale."; + qCWarning(asset_backup) << "Backing up asset mappings that might be stale."; } AssetServerBackup backup; @@ -180,43 +197,65 @@ void AssetsBackupHandler::createBackup(QuaZip& zip) { QuaZipFile zipFile { &zip }; if (!zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(MAPPINGS_FILE))) { - qCDebug(backup_supervisor) << "Could not open zip file:" << zipFile.getZipError(); + qCDebug(asset_backup) << "Could not open zip file:" << zipFile.getZipError(); return; } zipFile.write(document.toJson()); zipFile.close(); if (zipFile.getZipError() != UNZ_OK) { - qCDebug(backup_supervisor) << "Could not close zip file: " << zipFile.getZipError(); + qCDebug(asset_backup) << "Could not close zip file: " << zipFile.getZipError(); return; } _backups.push_back(backup); } void AssetsBackupHandler::recoverBackup(QuaZip& zip) { + Q_ASSERT(QThread::currentThread() == thread()); + if (operationInProgress()) { - qCWarning(backup_supervisor) << "There is already a backup/restore in progress."; + qCWarning(asset_backup) << "There is already a backup/restore in progress."; return; } if (_lastMappingsRefresh == 0) { - qCWarning(backup_supervisor) << "Current mappings not yet loaded."; + qCWarning(asset_backup) << "Current mappings not yet loaded."; return; } static constexpr quint64 MAX_REFRESH_TIME = 15 * 60 * 1000 * 1000; if (usecTimestampNow() - _lastMappingsRefresh > MAX_REFRESH_TIME) { - qCWarning(backup_supervisor) << "Current asset mappings that might be stale."; + qCWarning(asset_backup) << "Current asset mappings that might be stale."; } - startOperation(); - auto it = find_if(begin(_backups), end(_backups), [&](const std::vector::value_type& value) { return value.filePath == zip.getZipName(); }); if (it == end(_backups)) { - qCDebug(backup_supervisor) << "Could not find backup" << zip.getZipName() << "to restore."; - stopOperation(); - return; + qCDebug(asset_backup) << "Could not find backup" << zip.getZipName() << "to restore."; + + loadBackup(zip); + + QuaZipDir zipDir { &zip, ZIP_ASSETS_FOLDER }; + + auto assetNames = zipDir.entryList(QDir::Files); + for (const auto& asset : assetNames) { + if (AssetUtils::isValidHash(asset)) { + if (!zip.setCurrentFile(MAPPINGS_FILE)) { + qCCritical(asset_backup) << "Failed to find" << asset << "while recovering backup"; + qCCritical(asset_backup) << " Error:" << zip.getZipError(); + continue; + } + + QuaZipFile zipFile { &zip }; + if (!zipFile.open(QFile::ReadOnly)) { + qCCritical(asset_backup) << "Could not unzip asset file:" << asset; + qCCritical(asset_backup) << " Error:" << zip.getZipError(); + continue; + } + + writeAssetFile(asset, zipFile.readAll()); + } + } } const auto& newMappings = it->mappings; @@ -226,8 +265,10 @@ void AssetsBackupHandler::recoverBackup(QuaZip& zip) { } void AssetsBackupHandler::deleteBackup(QuaZip& zip) { + Q_ASSERT(QThread::currentThread() == thread()); + if (operationInProgress()) { - qCWarning(backup_supervisor) << "There is a backup/restore in progress."; + qCWarning(asset_backup) << "There is a backup/restore in progress."; return; } @@ -235,7 +276,7 @@ void AssetsBackupHandler::deleteBackup(QuaZip& zip) { return value.filePath == zip.getZipName(); }); if (it == end(_backups)) { - qCDebug(backup_supervisor) << "Could not find backup" << zip.getZipName() << "to delete."; + qCDebug(asset_backup) << "Could not find backup" << zip.getZipName() << "to delete."; return; } @@ -244,8 +285,10 @@ void AssetsBackupHandler::deleteBackup(QuaZip& zip) { } void AssetsBackupHandler::consolidateBackup(QuaZip& zip) { + Q_ASSERT(QThread::currentThread() == thread()); + if (operationInProgress()) { - qCWarning(backup_supervisor) << "There is a backup/restore in progress."; + qCWarning(asset_backup) << "There is a backup/restore in progress."; return; } QFileInfo zipInfo(zip.getZipName()); @@ -255,7 +298,7 @@ void AssetsBackupHandler::consolidateBackup(QuaZip& zip) { return info.fileName() == zipInfo.fileName(); }); if (it == end(_backups)) { - qCDebug(backup_supervisor) << "Could not find backup" << zip.getZipName() << "to consolidate."; + qCDebug(asset_backup) << "Could not find backup" << zip.getZipName() << "to consolidate."; return; } @@ -265,20 +308,19 @@ void AssetsBackupHandler::consolidateBackup(QuaZip& zip) { QDir assetsDir { _assetsDirectory }; QFile file { assetsDir.filePath(hash) }; if (!file.open(QFile::ReadOnly)) { - qCCritical(backup_supervisor) << "Could not open asset file" << file.fileName(); + qCCritical(asset_backup) << "Could not open asset file" << file.fileName(); continue; } QuaZipFile zipFile { &zip }; - static const QString ZIP_ASSETS_FOLDER = "files/"; - if (!zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(ZIP_ASSETS_FOLDER + hash))) { - qCDebug(backup_supervisor) << "Could not open zip file:" << zipFile.getZipError(); + if (!zipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(ZIP_ASSETS_FOLDER + "/" + hash))) { + qCDebug(asset_backup) << "Could not open zip file:" << zipFile.getZipError(); continue; } zipFile.write(file.readAll()); zipFile.close(); if (zipFile.getZipError() != UNZ_OK) { - qCDebug(backup_supervisor) << "Could not close zip file: " << zipFile.getZipError(); + qCDebug(asset_backup) << "Could not close zip file: " << zipFile.getZipError(); continue; } } @@ -300,8 +342,8 @@ void AssetsBackupHandler::refreshMappings() { downloadMissingFiles(_currentMappings); } else { - qCCritical(backup_supervisor) << "Could not refresh asset server mappings."; - qCCritical(backup_supervisor) << " Error:" << request->getErrorString(); + qCCritical(asset_backup) << "Could not refresh asset server mappings."; + qCCritical(asset_backup) << " Error:" << request->getErrorString(); } request->deleteLater(); @@ -341,14 +383,14 @@ void AssetsBackupHandler::downloadNextMissingFile() { QObject::connect(assetRequest, &AssetRequest::finished, this, [this](AssetRequest* request) { if (request->getError() == AssetRequest::NoError) { - qCDebug(backup_supervisor) << "Backing up asset" << request->getHash(); + qCDebug(asset_backup) << "Backing up asset" << request->getHash(); bool success = writeAssetFile(request->getHash(), request->getData()); if (!success) { - qCCritical(backup_supervisor) << "Failed to write asset file" << request->getHash(); + qCCritical(asset_backup) << "Failed to write asset file" << request->getHash(); } } else { - qCCritical(backup_supervisor) << "Failed to backup asset" << request->getHash(); + qCCritical(asset_backup) << "Failed to backup asset" << request->getHash(); } _assetsLeftToRequest.erase(request->getHash()); @@ -364,13 +406,13 @@ bool AssetsBackupHandler::writeAssetFile(const AssetUtils::AssetHash& hash, cons QDir assetsDir { _assetsDirectory }; QFile file { assetsDir.filePath(hash) }; if (!file.open(QFile::WriteOnly)) { - qCCritical(backup_supervisor) << "Could not open backup file" << file.fileName(); + qCCritical(asset_backup) << "Could not open asset file for write:" << file.fileName(); return false; } auto bytesWritten = file.write(data); if (bytesWritten != data.size()) { - qCCritical(backup_supervisor) << "Could not write data to file" << file.fileName(); + qCCritical(asset_backup) << "Could not write data to file" << file.fileName(); file.remove(); return false; } @@ -410,9 +452,9 @@ void AssetsBackupHandler::computeServerStateDifference(const AssetUtils::Mapping } } - qCDebug(backup_supervisor) << "Mappings to set:" << _mappingsLeftToSet.size(); - qCDebug(backup_supervisor) << "Mappings to del:" << _mappingsLeftToDelete.size(); - qCDebug(backup_supervisor) << "Assets to upload:" << _assetsLeftToUpload.size(); + qCDebug(asset_backup) << "Mappings to set:" << _mappingsLeftToSet.size(); + qCDebug(asset_backup) << "Mappings to del:" << _mappingsLeftToDelete.size(); + qCDebug(asset_backup) << "Assets to upload:" << _assetsLeftToUpload.size(); } void AssetsBackupHandler::restoreAllAssets() { @@ -420,6 +462,8 @@ void AssetsBackupHandler::restoreAllAssets() { } void AssetsBackupHandler::restoreNextAsset() { + startOperation(); + if (_assetsLeftToUpload.empty()) { updateMappings(); return; @@ -435,8 +479,8 @@ void AssetsBackupHandler::restoreNextAsset() { QObject::connect(request, &AssetUpload::finished, this, [this](AssetUpload* request) { if (request->getError() != AssetUpload::NoError) { - qCCritical(backup_supervisor) << "Failed to restore asset:" << request->getFilename(); - qCCritical(backup_supervisor) << " Error:" << request->getErrorString(); + qCCritical(asset_backup) << "Failed to restore asset:" << request->getFilename(); + qCCritical(asset_backup) << " Error:" << request->getErrorString(); } restoreNextAsset(); @@ -453,8 +497,8 @@ void AssetsBackupHandler::updateMappings() { auto request = assetClient->createSetMappingRequest(mapping.first, mapping.second); QObject::connect(request, &SetMappingRequest::finished, this, [this](SetMappingRequest* request) { if (request->getError() != MappingRequest::NoError) { - qCCritical(backup_supervisor) << "Failed to set mapping:" << request->getPath(); - qCCritical(backup_supervisor) << " Error:" << request->getErrorString(); + qCCritical(asset_backup) << "Failed to set mapping:" << request->getPath(); + qCCritical(asset_backup) << " Error:" << request->getErrorString(); } if (--_mappingRequestsInFlight == 0) { @@ -472,8 +516,8 @@ void AssetsBackupHandler::updateMappings() { auto request = assetClient->createDeleteMappingsRequest(_mappingsLeftToDelete); QObject::connect(request, &DeleteMappingsRequest::finished, this, [this](DeleteMappingsRequest* request) { if (request->getError() != MappingRequest::NoError) { - qCCritical(backup_supervisor) << "Failed to delete mappings"; - qCCritical(backup_supervisor) << " Error:" << request->getErrorString(); + qCCritical(asset_backup) << "Failed to delete mappings"; + qCCritical(asset_backup) << " Error:" << request->getErrorString(); } if (--_mappingRequestsInFlight == 0) { diff --git a/domain-server/src/AssetsBackupHandler.h b/domain-server/src/AssetsBackupHandler.h index b78206b7b1..2ef454998e 100644 --- a/domain-server/src/AssetsBackupHandler.h +++ b/domain-server/src/AssetsBackupHandler.h @@ -40,6 +40,7 @@ public: bool operationInProgress() const { return _operationInProgress; } private: + void setupRefreshTimer(); void refreshMappings(); void refreshAssetsInBackups(); From 3297e39c144581788015b5ea4cd5bc52505fda0a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 15 Feb 2018 13:39:18 -0800 Subject: [PATCH 6/6] CR --- domain-server/src/AssetsBackupHandler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/domain-server/src/AssetsBackupHandler.cpp b/domain-server/src/AssetsBackupHandler.cpp index a9f56a0c5b..ae9cb58343 100644 --- a/domain-server/src/AssetsBackupHandler.cpp +++ b/domain-server/src/AssetsBackupHandler.cpp @@ -58,7 +58,6 @@ void AssetsBackupHandler::setupRefreshTimer() { }); QObject::connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, [this](SharedNodePointer node) { if (node->getType() == NodeType::AssetServer) { - // run immediately for the first time. _mappingsRefreshTimer.stop(); } }); @@ -240,7 +239,7 @@ void AssetsBackupHandler::recoverBackup(QuaZip& zip) { auto assetNames = zipDir.entryList(QDir::Files); for (const auto& asset : assetNames) { if (AssetUtils::isValidHash(asset)) { - if (!zip.setCurrentFile(MAPPINGS_FILE)) { + if (!zip.setCurrentFile(zipDir.filePath(asset))) { qCCritical(asset_backup) << "Failed to find" << asset << "while recovering backup"; qCCritical(asset_backup) << " Error:" << zip.getZipError(); continue;