From cdd7b7e293870e3c378df8331e65b94f09994535 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 25 Feb 2017 23:08:38 -0600 Subject: [PATCH] Begin remove support --- SiaDrive.Api/UploadManager.cpp | 118 ++++++++++++++++++++++----------- SiaDrive.Api/UploadManager.h | 5 +- 2 files changed, 83 insertions(+), 40 deletions(-) diff --git a/SiaDrive.Api/UploadManager.cpp b/SiaDrive.Api/UploadManager.cpp index 13d5c35..7f7ea1d 100644 --- a/SiaDrive.Api/UploadManager.cpp +++ b/SiaDrive.Api/UploadManager.cpp @@ -8,6 +8,7 @@ using namespace Sia::Api; #define TABLE_CREATE L"create table if not exists %s (%s);" #define UPLOAD_TABLE L"upload_table" #define UPLOAD_TABLE_COLUMNS L"id integer primary key autoincrement, sia_path text unique not null, file_path text unique not null, sd_file_path text unique not null, status integer not null" +#define QUERY_STATUS "select id, sia_path, file_path, sd_file_path, status from upload_table where sia_path=@sia_path order by id desc limit 1;" #define QUERY_UPLOADS_BY_STATUS "select id, sia_path, status from upload_table where status=@status order by id desc limit 1;" #define QUERY_UPLOADS_BY_2_STATUS "select id, sia_path, status from upload_table where (status=@status1 or status=@status2) order by id desc limit 1;" #define QUERY_UPLOADS_BY_SIA_PATH "select id, sia_path, status from upload_table where sia_path=@sia_path order by id desc limit 1;" @@ -77,6 +78,9 @@ String CUploadManager::UploadStatusToString(const UploadStatus& uploadStatus) case UploadStatus::Queued: return L"Queued"; + case UploadStatus::Remove: + return L"Remove"; + case UploadStatus::Uploading: return L"Uploading"; @@ -119,57 +123,74 @@ void CUploadManager::FileThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig } } -void CUploadManager::NewFileAction(const String& siaPath, const String& filePath, const String& tempSourcePath, const String& siaDriveFilePath) +void CUploadManager::FileAction(const String& siaPath, const String& filePath, const String& tempSourcePath, const String& siaDriveFilePath, const bool& remove) { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath))); - if (RetryableAction(::CopyFile(filePath.c_str(), tempSourcePath.c_str(), FALSE), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) { - // Delete existing '.siadrive' file, if found - // !!Should never come here. If so, there was a problem with startup clean-up - if (!RetryDeleteFileIfExists(siaDriveFilePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); - } + std::lock_guard l(_fileActionMutex); + _activeSiaPath = siaPath; + } - // Rename '.siadrive.temp' to '.siadrive' - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath))); - if (RetryableAction(::MoveFile(tempSourcePath.c_str(), siaDriveFilePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + if (remove) + { + + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath))); + if (RetryableAction(::CopyFile(filePath.c_str(), tempSourcePath.c_str(), FALSE), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) { - std::lock_guard l(_uploadMutex); - SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed) - if (statusUpdated && !RetryDeleteFileIfExists(tempSourcePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - } - } - else - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath, siaDriveFilePath))); - if (!RetryDeleteFileIfExists(tempSourcePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - } - + // Delete existing '.siadrive' file, if found + // !!Should never come here. If so, there was a problem with startup clean-up if (!RetryDeleteFileIfExists(siaDriveFilePath)) { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); } + // Rename '.siadrive.temp' to '.siadrive' + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath))); + if (RetryableAction(::MoveFile(tempSourcePath.c_str(), siaDriveFilePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + { + std::lock_guard l(_uploadMutex); + SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed) + if (statusUpdated && !RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath, siaDriveFilePath))); + if (!RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + + if (!RetryDeleteFileIfExists(siaDriveFilePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); + } + + // Requeued + } + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + + // If temp copy fails, try to delete + // If partial copy and file is unable to be deleted, log warning + if (!RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + // Requeued } } - else + { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - - // If temp copy fails, try to delete - // If partial copy and file is unable to be deleted, log warning - if (!RetryDeleteFileIfExists(tempSourcePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - } - - // Requeued + std::lock_guard l(_fileActionMutex); + _activeSiaPath.empty(); } } @@ -383,7 +404,7 @@ UploadError CUploadManager::AddOrUpdate(const String& siaPath, String filePath) { // Queue file upload operation std::lock_guard l2(_fileQueueMutex); - _fileQueue.push_back([=]() { this->NewFileAction(siaPath, filePath, tempSourcePath, siaDriveFilePath); }); + _fileQueue.push_back([=]() { this->FileAction(siaPath, filePath, tempSourcePath, siaDriveFilePath, false); }); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(NewFileAdded(siaPath, filePath, siaDriveFilePath))); } } @@ -422,5 +443,24 @@ void CUploadManager::PurgeErrorStatus() UploadError CUploadManager::Remove(const String& siaPath) { UploadError ret = UploadError::Success; + std::lock_guard l(_uploadMutex); + try + { + bool remove = false; + SQLite::Statement query(_uploadDatabase, QUERY_STATUS); + query.bind("@sia_path", CW2A(siaPath.c_str()).m_psz); + + if (remove) + { + std::lock_guard l2(_fileQueueMutex); + _fileQueue.push_back([=]() { this->FileAction(siaPath, nullptr, nullptr, nullptr, true); }); + } + } + catch (SQLite::Exception e) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred(e))); + ret = UploadError::DatabaseError; + + } return ret; } \ No newline at end of file diff --git a/SiaDrive.Api/UploadManager.h b/SiaDrive.Api/UploadManager.h index 74b1d36..110298d 100644 --- a/SiaDrive.Api/UploadManager.h +++ b/SiaDrive.Api/UploadManager.h @@ -18,6 +18,7 @@ public: Queued, Modified, Uploading, + Remove, Complete, Error }; @@ -50,10 +51,12 @@ private: std::mutex _uploadMutex; CAutoThread _fileThread; std::mutex _fileQueueMutex; + std::mutex _fileActionMutex; + String _activeSiaPath; std::deque> _fileQueue; private: - void NewFileAction(const String& siaPath, const String& filePath, const String& tempSourcePath, const String& siaDriveFilePath); + void FileAction(const String& siaPath, const String& filePath, const String& tempSourcePath, const String& siaDriveFilePath, const bool& remove); protected: virtual void AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig) override;