mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-23 04:30:09 -05:00
Make URLSynchronization and HTTPSynchronization download into temporary files and if the download succeeds, transactionally move the temporary file into the correct destination
This commit is contained in:
@@ -22,27 +22,27 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "httpsynchronization.h"
|
||||
#include <modules/sync/syncs/httpsynchronization.h>
|
||||
|
||||
#include <modules/sync/syncmodule.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/util/httprequest.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* KeyVersion = "Version";
|
||||
|
||||
constexpr const char* TempSuffix = ".tmp";
|
||||
|
||||
constexpr const char* QueryKeyIdentifier = "identifier";
|
||||
constexpr const char* QueryKeyFileVersion = "file_version";
|
||||
constexpr const char* QueryKeyApplicationVersion = "application_version";
|
||||
@@ -214,8 +214,8 @@ bool HttpSynchronization::trySyncFromUrl(std::string listUrl) {
|
||||
std::string filename = line.substr(lastSlash + 1);
|
||||
|
||||
std::string fileDestination = directory() +
|
||||
ghoul::filesystem::FileSystem::PathSeparator +
|
||||
filename;
|
||||
ghoul::filesystem::FileSystem::PathSeparator +
|
||||
filename + TempSuffix;
|
||||
|
||||
downloads.push_back(std::make_unique<AsyncHttpFileDownload>(
|
||||
line, fileDestination, HttpFileDownload::Overwrite::Yes));
|
||||
@@ -256,7 +256,31 @@ bool HttpSynchronization::trySyncFromUrl(std::string listUrl) {
|
||||
bool failed = false;
|
||||
for (std::unique_ptr<AsyncHttpFileDownload>& d : downloads) {
|
||||
d->wait();
|
||||
if (!d->hasSucceeded()) {
|
||||
if (d->hasSucceeded()) {
|
||||
// If we are forcing the override, we download to a temporary file
|
||||
// first, so when we are done here, we need to rename the file to the
|
||||
// original name
|
||||
|
||||
const std::string& tempName = d->destination();
|
||||
std::string originalName = tempName.substr(
|
||||
0,
|
||||
tempName.size() - strlen(TempSuffix)
|
||||
);
|
||||
|
||||
FileSys.deleteFile(originalName);
|
||||
int success = rename(tempName.c_str(), originalName.c_str());
|
||||
if (success != 0) {
|
||||
LERRORC(
|
||||
"URLSynchronization",
|
||||
fmt::format(
|
||||
"Error renaming file {} to {}", tempName, originalName
|
||||
)
|
||||
);
|
||||
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,11 +35,14 @@
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyUrl = "Url";
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* KeyOverride = "Override";
|
||||
|
||||
constexpr const char* TempSuffix = ".tmp";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -149,7 +152,7 @@ void UrlSynchronization::start() {
|
||||
|
||||
std::string fileDestination = directory() +
|
||||
ghoul::filesystem::FileSystem::PathSeparator +
|
||||
filename;
|
||||
filename += TempSuffix;
|
||||
|
||||
std::unique_ptr<AsyncHttpFileDownload> download =
|
||||
std::make_unique<AsyncHttpFileDownload>(
|
||||
@@ -189,7 +192,6 @@ void UrlSynchronization::start() {
|
||||
HttpRequest::RequestOptions opt;
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
fileDownload->start(opt);
|
||||
|
||||
}
|
||||
|
||||
startedAllDownloads = true;
|
||||
@@ -197,7 +199,31 @@ void UrlSynchronization::start() {
|
||||
bool failed = false;
|
||||
for (std::unique_ptr<AsyncHttpFileDownload>& d : downloads) {
|
||||
d->wait();
|
||||
if (!d->hasSucceeded()) {
|
||||
if (d->hasSucceeded()) {
|
||||
// If we are forcing the override, we download to a temporary file first,
|
||||
// so when we are done here, we need to rename the file to the original
|
||||
// name
|
||||
|
||||
const std::string& tempName = d->destination();
|
||||
std::string originalName = tempName.substr(
|
||||
0,
|
||||
tempName.size() - strlen(TempSuffix)
|
||||
);
|
||||
|
||||
FileSys.deleteFile(originalName);
|
||||
int success = rename(tempName.c_str(), originalName.c_str());
|
||||
if (success != 0) {
|
||||
LERRORC(
|
||||
"URLSynchronization",
|
||||
fmt::format(
|
||||
"Error renaming file {} to {}", tempName, originalName
|
||||
)
|
||||
);
|
||||
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
@@ -206,7 +232,7 @@ void UrlSynchronization::start() {
|
||||
createSyncFile();
|
||||
}
|
||||
else {
|
||||
for (auto& d : downloads) {
|
||||
for (std::unique_ptr<AsyncHttpFileDownload>& d : downloads) {
|
||||
d->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user