1
0

Fix stuffs

This commit is contained in:
Scott E. Graves
2017-03-27 23:06:16 -05:00
parent 4a6e99f925
commit ca6390fff3
6 changed files with 79 additions and 233 deletions

View File

@@ -41,6 +41,7 @@ public:
FilePath& RemoveFileName(); FilePath& RemoveFileName();
FilePath& MakeAbsolute(); FilePath& MakeAbsolute();
FilePath& SkipRoot(); FilePath& SkipRoot();
FilePath& StripToFileName();
public: public:
FilePath& operator=(const FilePath& filePath); FilePath& operator=(const FilePath& filePath);

View File

@@ -18,7 +18,6 @@ public:
enum class _UploadStatus : unsigned enum class _UploadStatus : unsigned
{ {
NotFound, NotFound,
Copying,
Queued, Queued,
Modified, Modified,
Uploading, Uploading,
@@ -53,17 +52,11 @@ public:
private: private:
SQLite::Database _uploadDatabase; SQLite::Database _uploadDatabase;
std::mutex _uploadMutex; std::mutex _uploadMutex;
CAutoThread _fileThread;
std::mutex _fileQueueMutex;
std::mutex _fileActionMutex;
SString _activeSiaPath; SString _activeSiaPath;
std::deque<std::function<void()>> _fileQueue;
private: private:
void FileAction(const CSiaCurl& siaCurl, const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath, const bool& remove);
void FileThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig);
void HandleFileRemove(const CSiaCurl& siaCurl, const SString& siaPath, const SString& siaDriveFilePath); void HandleFileRemove(const CSiaCurl& siaCurl, const SString& siaPath, const SString& siaDriveFilePath);
void HandleAddFile(const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath); bool CreateSiaDriveFile(const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath);
void UpdateFileQueueOnStartup(); void UpdateFileQueueOnStartup();
void DeleteFilesRemovedFromSia(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig, const bool& isStartup = false); void DeleteFilesRemovedFromSia(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig, const bool& isStartup = false);
@@ -121,9 +114,10 @@ class UploadAddedToQueue :
public CEvent public CEvent
{ {
public: public:
UploadAddedToQueue(const SString& siaPath, const SString& filePath) : UploadAddedToQueue(const SString& siaPath, const SString& filePath, const SString& siaDriveFilePath) :
_siaPath(siaPath), _siaPath(siaPath),
_filePath(filePath) _filePath(filePath),
_siaDriveFilePath(siaDriveFilePath)
{ {
} }
@@ -136,16 +130,17 @@ public:
private: private:
const SString _siaPath; const SString _siaPath;
const SString _filePath; const SString _filePath;
const SString _siaDriveFilePath;
public: public:
virtual SString GetSingleLineMessage() const override virtual SString GetSingleLineMessage() const override
{ {
return L"UploadAddedToQueue|SP|" + _siaPath + L"|FP|" + _filePath; return L"UploadAddedToQueue|SP|" + _siaPath + L"|FP|" + _filePath + "|SFP|" + _siaDriveFilePath;
} }
virtual std::shared_ptr<CEvent> Clone() const override virtual std::shared_ptr<CEvent> Clone() const override
{ {
return std::shared_ptr<CEvent>(new UploadAddedToQueue(_siaPath, _filePath)); return std::shared_ptr<CEvent>(new UploadAddedToQueue(_siaPath, _filePath, _siaDriveFilePath));
} }
}; };
@@ -751,40 +746,6 @@ public:
} }
}; };
class NewFileAdded :
public CEvent
{
public:
NewFileAdded(const SString& siaPath, const SString& filePath, const SString& siaDriveFilePath) :
_siaPath(siaPath),
_filePath(filePath),
_siaDriveFilePath(siaDriveFilePath)
{
}
public:
virtual ~NewFileAdded()
{
}
private:
const SString _siaPath;
const SString _filePath;
const SString _siaDriveFilePath;
public:
virtual SString GetSingleLineMessage() const override
{
return L"NewFileAdded|SP|" + _siaPath + L"|FP|" + _filePath + L"|SDP|" + _siaDriveFilePath;
}
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new NewFileAdded(_siaPath, _filePath, _siaDriveFilePath));
}
};
class FileRemoveAdded : class FileRemoveAdded :
public CEvent public CEvent
{ {

View File

@@ -37,7 +37,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
settings.no_sandbox = true; settings.no_sandbox = true;
settings.remote_debugging_port = 8080; settings.remote_debugging_port = 8080;
#ifdef _DEBUG #ifdef _DEBUG
settings.single_process = false; settings.single_process = true;
#endif #endif
CefInitialize(mainArgs, settings, app, nullptr); CefInitialize(mainArgs, settings, app, nullptr);

View File

@@ -241,3 +241,14 @@ FilePath& FilePath::MakeAbsolute()
return *this; return *this;
} }
FilePath& FilePath::StripToFileName()
{
#ifdef _WIN32
_path = ::PathFindFileName(&_path[0]);
#else
a
#endif
return *this;
}

View File

@@ -1,10 +1,8 @@
#include <SQLiteCpp/Exception.h> #include <SQLiteCpp/Exception.h>
#include <uploadmanager.h> #include <uploadmanager.h>
#include <siaapi.h> #include <siaapi.h>
#include <eventsystem.h> #include <eventsystem.h>
#include <siadriveconfig.h> #include <siadriveconfig.h>
#include <sqlite3.h>
#include <filepath.h> #include <filepath.h>
using namespace Sia::Api; using namespace Sia::Api;
@@ -67,9 +65,6 @@ SString CUploadManager::UploadStatusToString(const UploadStatus& uploadStatus)
case UploadStatus::Complete: case UploadStatus::Complete:
return L"Complete"; return L"Complete";
case UploadStatus::Copying:
return L"Copying";
case UploadStatus::Error: case UploadStatus::Error:
return L"Error"; return L"Error";
@@ -95,8 +90,7 @@ SString CUploadManager::UploadStatusToString(const UploadStatus& uploadStatus)
CUploadManager::CUploadManager(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig) : CUploadManager::CUploadManager(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig) :
CAutoThread(siaCurl, siaDriveConfig), CAutoThread(siaCurl, siaDriveConfig),
_uploadDatabase(siaDriveConfig->GetRenter_UploadDbFilePath(), SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE), _uploadDatabase(siaDriveConfig->GetRenter_UploadDbFilePath(), SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE)
_fileThread(siaCurl, siaDriveConfig, [this](const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig) { this->FileThreadCallback(siaCurl, siaDriveConfig); })
{ {
CreateTableIfNotFound(&_uploadDatabase, UPLOAD_TABLE, UPLOAD_TABLE_COLUMNS); CreateTableIfNotFound(&_uploadDatabase, UPLOAD_TABLE, UPLOAD_TABLE_COLUMNS);
@@ -119,13 +113,11 @@ CUploadManager::CUploadManager(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriv
// Begin normal processing // Begin normal processing
StartAutoThread(); StartAutoThread();
_fileThread.StartAutoThread();
} }
CUploadManager::~CUploadManager() CUploadManager::~CUploadManager()
{ {
// Stop all processing // Stop all processing
_fileThread.StopAutoThread();
StopAutoThread(); StopAutoThread();
} }
@@ -134,9 +126,8 @@ void CUploadManager::UpdateFileQueueOnStartup()
try try
{ {
// Re-add Copying and Remove // Re-add Copying and Remove
SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_SIA_PATH_AND_2_STATUS); SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_STATUS);
query.bind("@status1", static_cast<unsigned>(UploadStatus::Copying)); query.bind("@status", static_cast<unsigned>(UploadStatus::Remove));
query.bind("@status1", static_cast<unsigned>(UploadStatus::Remove));
while (query.executeStep()) while (query.executeStep())
{ {
SString siaPath = static_cast<const char*>(query.getColumn(query.getColumnIndex("sia_path"))); SString siaPath = static_cast<const char*>(query.getColumn(query.getColumnIndex("sia_path")));
@@ -152,16 +143,10 @@ void CUploadManager::UpdateFileQueueOnStartup()
SString siaDriveFileName = GenerateSha256(&filePath[3]) + L".siadrive"; SString siaDriveFileName = GenerateSha256(&filePath[3]) + L".siadrive";
FilePath tempSourcePath(rootPath, (siaDriveFileName + L".temp")); FilePath tempSourcePath(rootPath, (siaDriveFileName + L".temp"));
std::lock_guard<std::mutex> l(_fileQueueMutex);
if (uploadStatus == UploadStatus::Remove) if (uploadStatus == UploadStatus::Remove)
{ {
_fileQueue.push_back([=]() { this->FileAction(CSiaCurl(GetHostConfig()), siaPath, filePath, "", siaDriveFilePath, true); });
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath)));
} this->HandleFileRemove(CSiaCurl(GetHostConfig()), siaPath, siaDriveFilePath);
else
{
_fileQueue.push_back([=]() { this->FileAction(CSiaCurl(GetHostConfig()), siaPath, filePath, tempSourcePath, siaDriveFilePath, false); });
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(NewFileAdded(siaPath, filePath, siaDriveFilePath)));
} }
} }
} }
@@ -192,24 +177,6 @@ void CUploadManager::DeleteFilesRemovedFromSia(const CSiaCurl& siaCurl, CSiaDriv
} }
} }
void CUploadManager::FileThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig)
{
std::function<void()> nextFile = nullptr;
{
std::lock_guard<std::mutex> l(_fileQueueMutex);
if (_fileQueue.size())
{
nextFile = _fileQueue.front();
_fileQueue.pop_front();
}
}
if (nextFile)
{
nextFile();
}
}
void CUploadManager::HandleFileRemove(const CSiaCurl& siaCurl, const SString& siaPath, const SString& siaDriveFilePath) void CUploadManager::HandleFileRemove(const CSiaCurl& siaCurl, const SString& siaPath, const SString& siaDriveFilePath)
{ {
try try
@@ -244,11 +211,9 @@ void CUploadManager::HandleFileRemove(const CSiaCurl& siaCurl, const SString& si
if (deleteFromDb) if (deleteFromDb)
{ {
json response; json response;
SiaCurlError cerror = siaCurl.Post(SString(L"/renter/delete") + siaPath, {}, response); SiaCurlError cerror = siaCurl.Post(SString(L"/renter/delete/") + siaPath, {}, response);
if (ApiSuccess(cerror)) if (ApiSuccess(cerror))
{ {
// TODO validate response
SQLite::Statement del(_uploadDatabase, DELETE_UPLOAD); SQLite::Statement del(_uploadDatabase, DELETE_UPLOAD);
del.bind("@sia_path", SString::ToUtf8(siaPath).c_str()); del.bind("@sia_path", SString::ToUtf8(siaPath).c_str());
if (del.exec() == 1) if (del.exec() == 1)
@@ -275,129 +240,58 @@ void CUploadManager::HandleFileRemove(const CSiaCurl& siaCurl, const SString& si
} }
} }
void CUploadManager::HandleAddFile(const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath) bool CUploadManager::CreateSiaDriveFile(const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath)
{ {
// Check for retry condition bool ret = false;
if (!FilePath(tempSourcePath).IsFile() && FilePath(siaDriveFilePath).IsFile()) CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath)));
if (RetryableAction(::CopyFile(filePath.str().c_str(), tempSourcePath.str().c_str(), FALSE), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS))
{ {
try // Delete existing '.siadrive' file, if found
// !!Should never come here. If so, there was a problem with startup clean-up
if (!RetryDeleteFileIfExists(siaDriveFilePath))
{ {
std::lock_guard<std::mutex> l(_uploadMutex); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath)));
SQLite::Statement query(_uploadDatabase, QUERY_STATUS);
query.bind("@sia_path", SString::ToUtf8(siaPath).c_str());
if (query.executeStep())
{
UploadStatus uploadStatus = static_cast<UploadStatus>(static_cast<unsigned>(query.getColumn(query.getColumnIndex("status"))));
if (uploadStatus == UploadStatus::Copying)
{
if (RetryDeleteFileIfExists(siaDriveFilePath))
{
SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed)
}
else
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath)));
}
}
}
} }
catch (SQLite::Exception e)
// Rename '.siadrive.temp' to '.siadrive'
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath)));
if (RetryableAction(::MoveFile(tempSourcePath.str().c_str(), siaDriveFilePath.str().c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS))
{ {
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred(e))); if (RetryDeleteFileIfExists(tempSourcePath))
}
}
else
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath)));
if (RetryableAction(::CopyFile(filePath.str().c_str(), tempSourcePath.str().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))); ret = true;
} }
else
// Rename '.siadrive.temp' to '.siadrive'
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath)));
if (RetryableAction(::MoveFile(tempSourcePath.str().c_str(), siaDriveFilePath.str().c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS))
{ {
if (!RetryDeleteFileIfExists(tempSourcePath)) CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath)));
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath)));
}
try
{
std::lock_guard<std::mutex> l(_uploadMutex);
SQLite::Statement query(_uploadDatabase, QUERY_STATUS);
query.bind("@sia_path", SString::ToUtf8(siaPath).c_str());
if (query.executeStep())
{
UploadStatus uploadStatus = static_cast<UploadStatus>(static_cast<unsigned>(query.getColumn(query.getColumnIndex("status"))));
if (uploadStatus == UploadStatus::Copying)
{
SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed)
}
}
}
catch (SQLite::Exception e)
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred(e)));
}
}
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 else
{ {
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath, siaDriveFilePath)));
// If temp copy fails, try to delete
// If partial copy and file is unable to be deleted, log warning
if (!RetryDeleteFileIfExists(tempSourcePath)) if (!RetryDeleteFileIfExists(tempSourcePath))
{ {
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath)));
} }
// Requeued if (!RetryDeleteFileIfExists(siaDriveFilePath))
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath)));
}
} }
} }
} else
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath)));
void CUploadManager::FileAction(const CSiaCurl& siaCurl, const SString& siaPath, const SString& filePath, const SString& tempSourcePath, const SString& siaDriveFilePath, const bool& remove) // If temp copy fails, try to delete
{ // If partial copy and file is unable to be deleted, log warning
{ if (!RetryDeleteFileIfExists(tempSourcePath))
std::lock_guard<std::mutex> l(_fileActionMutex); {
_activeSiaPath = siaPath; CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath)));
} }
}
if (remove) return ret;
{
HandleFileRemove(siaCurl, siaPath, siaDriveFilePath);
}
else
{
HandleAddFile(siaPath, filePath, tempSourcePath, siaDriveFilePath);
}
{
std::lock_guard<std::mutex> l(_fileActionMutex);
_activeSiaPath = "";
}
} }
void CUploadManager::AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig) void CUploadManager::AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig* siaDriveConfig)
@@ -415,7 +309,7 @@ void CUploadManager::AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig
std::lock_guard<std::mutex> l(_uploadMutex); std::lock_guard<std::mutex> l(_uploadMutex);
SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_2_STATUS); SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_2_STATUS);
query.bind("@status1", static_cast<unsigned>(UploadStatus::Uploading)); query.bind("@status1", static_cast<unsigned>(UploadStatus::Uploading));
query.bind("@status2", static_cast<unsigned>(UploadStatus::Modified)); query.bind("@status2", static_cast<unsigned>(UploadStatus::Modified));
fileTree->BuildTree(result); fileTree->BuildTree(result);
if (query.executeStep()) if (query.executeStep())
@@ -437,17 +331,15 @@ void CUploadManager::AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig
SET_STATUS(UploadStatus::Remove, ExternallyRemovedFileDetected, ModifyUploadStatusFailed) SET_STATUS(UploadStatus::Remove, ExternallyRemovedFileDetected, ModifyUploadStatusFailed)
if (statusUpdated) if (statusUpdated)
{ {
std::lock_guard<std::mutex> l2(_fileQueueMutex);
_fileQueue.push_back([=]() { this->FileAction(CSiaCurl(GetHostConfig()), siaPath, filePath, "", siaDriveFilePath, true); });
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath)));
this->HandleFileRemove(siaCurl, siaPath, siaDriveFilePath);
} }
} }
// Changed file detected // Changed file detected
else if (uploadStatus == UploadStatus::Modified) else if (uploadStatus == UploadStatus::Modified)
{ {
json response; json response;
SiaCurlError cerror = siaCurl.Post(SString(L"/renter/delete") + siaPath, {}, response); SiaCurlError cerror = siaCurl.Post(SString(L"/renter/delete/") + siaPath, {}, response);
if (ApiSuccess(cerror)) if (ApiSuccess(cerror))
{ {
// TODO validate response // TODO validate response
@@ -491,24 +383,26 @@ void CUploadManager::AutoThreadCallback(const CSiaCurl& siaCurl, CSiaDriveConfig
{ {
try try
{ {
// TODO Rethink this - could hang here for quite a while
std::lock_guard<std::mutex> l(_uploadMutex); std::lock_guard<std::mutex> l(_uploadMutex);
SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_STATUS); SQLite::Statement query(_uploadDatabase, QUERY_UPLOADS_BY_STATUS);
query.bind("@status", static_cast<unsigned>(UploadStatus::Queued)); query.bind("@status", static_cast<unsigned>(UploadStatus::Queued));
// Lock here - if file is modified again before a prior upload is complete, delete it and
// start again later
if (query.executeStep()) if (query.executeStep())
{ {
SString siaPath = static_cast<const char*>(query.getColumn(query.getColumnIndex("sia_path"))); SString siaPath = static_cast<const char*>(query.getColumn(query.getColumnIndex("sia_path")));
SString filePath = static_cast<const char*>(query.getColumn(query.getColumnIndex("file_path"))); SString filePath = static_cast<const char*>(query.getColumn(query.getColumnIndex("file_path")));
SString sdFilePath = static_cast<const char*>(query.getColumn(query.getColumnIndex("sd_file_path")));
// TODO Validate response if (CreateSiaDriveFile(siaPath, filePath, sdFilePath + ".temp", sdFilePath))
json response; {
SiaCurlError cerror = siaCurl.Post(SString(L"/renter/upload/") + siaPath, { {L"source", filePath} }, response); // TODO Validate response
if (ApiSuccess(cerror)) json response;
{ SiaCurlError cerror = siaCurl.Post(SString(L"/renter/upload/") + siaPath, { {L"source", filePath} }, response);
SET_STATUS(UploadStatus::Uploading, UploadToSiaStarted, ModifyUploadStatusFailed) if (ApiSuccess(cerror))
} {
SET_STATUS(UploadStatus::Uploading, UploadToSiaStarted, ModifyUploadStatusFailed)
}
}
} }
} }
catch (const SQLite::Exception& e) catch (const SQLite::Exception& e)
@@ -533,21 +427,6 @@ UploadStatus CUploadManager::GetUploadStatus(const SString& siaPath)
return uploadStatus; return uploadStatus;
} }
// The real source file is copied to a hidden file. The hidden filename is constructed by generating an SHA25 hash of the
// source path (all lowercase). '.siadrive.temp' will be used as the extension. After copy is successful, the extension
// is renamed to '.siadrive'. '.siadrive' files will be hidden/system and used by the Dokan API for file i/o until Sia upload
// is complete. If a change occurs, the file will be deleted from Sia (cancelling the in-progress upload) and renamed to the
// real source path. The process will then start over again as if the file was new.
// If the file has been fully uploaded, the hidden file should not exist, so rename will not occur; however, the file
// will be deleted from Sia and treated as new.
// Uploads will always use the real file. User i/o will occur against the hidden file temporarily. Since upload will take
// longer to handle than a normal file copy, this seems to be the best compromise for performance.
//
// Error Scenarios:
// Crash before db update to status copying - file will be re-uploaded automatically, if complete; otherwise, deleted
// Crash before copy begins - on startup, check for copying status with no .siadrive
// Crash during copy - on startup, check for copying status and delete .siadrive
// Crash after copy but before db update - on startup, check for copying status and delete .siadrive
UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath) UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath)
{ {
UploadError ret = UploadError::Success; UploadError ret = UploadError::Success;
@@ -568,6 +447,7 @@ UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath
query.bind("@sia_path", SString::ToUtf8(siaPath).c_str()); query.bind("@sia_path", SString::ToUtf8(siaPath).c_str());
query.bind("@status1", static_cast<unsigned>(UploadStatus::Uploading)); query.bind("@status1", static_cast<unsigned>(UploadStatus::Uploading));
query.bind("@status2", static_cast<unsigned>(UploadStatus::Modified)); query.bind("@status2", static_cast<unsigned>(UploadStatus::Modified));
// Check copying // Check copying
if (query.executeStep()) if (query.executeStep())
{ {
@@ -585,7 +465,6 @@ UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath
// TODO Case sensative file names? Going to be a bit of an issue. // TODO Case sensative file names? Going to be a bit of an issue.
SString siaDriveFileName = GenerateSha256(&filePath[3]) + L".siadrive"; SString siaDriveFileName = GenerateSha256(&filePath[3]) + L".siadrive";
FilePath siaDriveFilePath(rootPath, siaDriveFileName); FilePath siaDriveFilePath(rootPath, siaDriveFileName);
FilePath tempSourcePath(rootPath, (siaDriveFileName + L".temp"));
// Add to db // Add to db
try try
@@ -594,13 +473,10 @@ UploadError CUploadManager::AddOrUpdate(const SString& siaPath, SString filePath
insert.bind("@sia_path", SString::ToUtf8(siaPath).c_str()); insert.bind("@sia_path", SString::ToUtf8(siaPath).c_str());
insert.bind("@file_path", SString::ToUtf8(filePath).c_str()); insert.bind("@file_path", SString::ToUtf8(filePath).c_str());
insert.bind("@sd_file_path", SString::ToUtf8(siaDriveFileName).c_str()); insert.bind("@sd_file_path", SString::ToUtf8(siaDriveFileName).c_str());
insert.bind("@status", static_cast<unsigned>(UploadStatus::Copying)); insert.bind("@status", static_cast<unsigned>(UploadStatus::Queued));
if (insert.exec() == 1) if (insert.exec() == 1)
{ {
// Queue file upload operation CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(UploadAddedToQueue(siaPath, filePath, siaDriveFilePath)));
std::lock_guard<std::mutex> l2(_fileQueueMutex);
_fileQueue.push_back([=]() { this->FileAction(CSiaCurl(GetHostConfig()), siaPath, filePath, tempSourcePath, siaDriveFilePath, false); });
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(NewFileAdded(siaPath, filePath, siaDriveFilePath)));
} }
else else
{ {
@@ -650,7 +526,6 @@ UploadError CUploadManager::Remove(const SString& siaPath)
case UploadStatus::Complete: case UploadStatus::Complete:
case UploadStatus::Queued: case UploadStatus::Queued:
case UploadStatus::Modified: case UploadStatus::Modified:
case UploadStatus::Copying:
case UploadStatus::Uploading: case UploadStatus::Uploading:
{ {
SET_STATUS(UploadStatus::Remove, UploadStatusSetToRemoved, ModifyUploadStatusFailed) SET_STATUS(UploadStatus::Remove, UploadStatusSetToRemoved, ModifyUploadStatusFailed)
@@ -671,10 +546,8 @@ UploadError CUploadManager::Remove(const SString& siaPath)
if (remove) if (remove)
{ {
std::lock_guard<std::mutex> l2(_fileQueueMutex);
_fileQueue.push_back([=]() { this->FileAction(CSiaCurl(GetHostConfig()), siaPath, filePath, "", siaDriveFilePath, true); });
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(FileRemoveAdded(siaPath)));
this->HandleFileRemove(CSiaCurl(GetHostConfig()), siaPath, siaDriveFilePath);
} }
} }
} }

View File

@@ -486,7 +486,7 @@ private:
for (auto& file : fileList) for (auto& file : fileList)
{ {
FilePath fp = file->GetSiaPath(); FilePath fp = file->GetSiaPath();
fp.RemoveFileName(); fp.StripToFileName();
if (files.find(fp) == files.end()) if (files.find(fp) == files.end())
{ {
WIN32_FIND_DATA fd = { 0 }; WIN32_FIND_DATA fd = { 0 };
@@ -531,7 +531,7 @@ private:
NTSTATUS ret = STATUS_SUCCESS; NTSTATUS ret = STATUS_SUCCESS;
FilePath cachePath = GetCacheLocation(); FilePath cachePath = GetCacheLocation();
if (FilePath::DirSep == fileName) if (FilePath::DirSep != fileName)
{ {
cachePath.Append(fileName); cachePath.Append(fileName);
} }