mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 05:29:34 +02:00
Relay upoaded content.zip chunks to temp file
Entities uploads still build in-memory. Move out chunk handling to new routine.
This commit is contained in:
parent
cd00abd216
commit
22c3f5239a
5 changed files with 67 additions and 39 deletions
|
@ -60,7 +60,7 @@ $(document).ready(function(){
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
updateProgressBars($('.upload-content-progress'), Math.round((offset + nextChunkSize) * 100 / fileSize));
|
updateProgressBars($('.upload-content-progress'), (offset + nextChunkSize) * 100 / fileSize);
|
||||||
|
|
||||||
if (!isFinal) {
|
if (!isFinal) {
|
||||||
ajaxObject.done(function (data, textStatus, jqXHR)
|
ajaxObject.done(function (data, textStatus, jqXHR)
|
||||||
|
@ -210,7 +210,7 @@ $(document).ready(function(){
|
||||||
|
|
||||||
function updateProgressBars($progressBar, value) {
|
function updateProgressBars($progressBar, value) {
|
||||||
$progressBar.attr('aria-valuenow', value).attr('style', 'width: ' + value + '%');
|
$progressBar.attr('aria-valuenow', value).attr('style', 'width: ' + value + '%');
|
||||||
$progressBar.find('.ongoing-msg').html(" " + value + "% Complete");
|
$progressBar.find('.ongoing-msg').html(" " + Math.round(value) + "% Complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
function reloadBackupInformation() {
|
function reloadBackupInformation() {
|
||||||
|
|
|
@ -348,6 +348,27 @@ void DomainContentBackupManager::recoverFromUploadedBackup(MiniPromise::Promise
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DomainContentBackupManager::recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "recoverFromUploadedFile", Q_ARG(MiniPromise::Promise, promise),
|
||||||
|
Q_ARG(QString, uploadedFilename));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Recovering from uploaded file -" << uploadedFilename;
|
||||||
|
|
||||||
|
QFile uploadedFile(uploadedFilename);
|
||||||
|
QuaZip uploadedZip { &uploadedFile };
|
||||||
|
|
||||||
|
QString backupName = MANUAL_BACKUP_PREFIX + "uploaded.zip";
|
||||||
|
|
||||||
|
bool success = recoverFromBackupZip(backupName, uploadedZip);
|
||||||
|
|
||||||
|
promise->resolve({
|
||||||
|
{ "success", success }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<BackupItemInfo> DomainContentBackupManager::getAllBackups() {
|
std::vector<BackupItemInfo> DomainContentBackupManager::getAllBackups() {
|
||||||
|
|
||||||
QDir backupDir { _backupDirectory };
|
QDir backupDir { _backupDirectory };
|
||||||
|
|
|
@ -86,6 +86,7 @@ public slots:
|
||||||
void createManualBackup(MiniPromise::Promise promise, const QString& name);
|
void createManualBackup(MiniPromise::Promise promise, const QString& name);
|
||||||
void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName);
|
void recoverFromBackup(MiniPromise::Promise promise, const QString& backupName);
|
||||||
void recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup);
|
void recoverFromUploadedBackup(MiniPromise::Promise promise, QByteArray uploadedBackup);
|
||||||
|
void recoverFromUploadedFile(MiniPromise::Promise promise, QString uploadedFilename);
|
||||||
void deleteBackup(MiniPromise::Promise promise, const QString& backupName);
|
void deleteBackup(MiniPromise::Promise promise, const QString& backupName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -2268,17 +2268,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
uploadedFilename = formDataFieldsRegex.cap(2);
|
uploadedFilename = formDataFieldsRegex.cap(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pendingUploadedContent += firstFormData.second;
|
// Received a chunk
|
||||||
if (formItemName == "restore-file-chunk") {
|
processPendingContent(connection, formItemName, uploadedFilename, firstFormData.second);
|
||||||
// Received another chunk
|
|
||||||
connection->respond(HTTPConnection::StatusCode200);
|
|
||||||
} else if (formItemName == "restore-file-chunk-final") {
|
|
||||||
readPendingContent(connection, uploadedFilename);
|
|
||||||
} else if (formItemName == "restore-file") {
|
|
||||||
readPendingContent(connection, uploadedFilename);
|
|
||||||
} else {
|
|
||||||
connection->respond(HTTPConnection::StatusCode400);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// respond with a 400 for failure
|
// respond with a 400 for failure
|
||||||
connection->respond(HTTPConnection::StatusCode400);
|
connection->respond(HTTPConnection::StatusCode400);
|
||||||
|
@ -2527,37 +2518,51 @@ bool DomainServer::handleHTTPSRequest(HTTPSConnection* connection, const QUrl &u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::readPendingContent(HTTPConnection* connection, QString filename) {
|
bool DomainServer::processPendingContent(HTTPConnection* connection, QString itemName, QString filename, QByteArray dataChunk) {
|
||||||
if (filename.endsWith(".json", Qt::CaseInsensitive)
|
if (filename.endsWith(".zip", Qt::CaseInsensitive)) {
|
||||||
|| filename.endsWith(".json.gz", Qt::CaseInsensitive)) {
|
static const QString TEMPORARY_CONTENT_FILEPATH { QDir::tempPath() + "/hifiUploadContent_XXXXXX.zip" };
|
||||||
// invoke our method to hand the new octree file off to the octree server
|
|
||||||
QMetaObject::invokeMethod(this, "handleOctreeFileReplacement",
|
|
||||||
Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent));
|
|
||||||
|
|
||||||
// respond with a 200 for success
|
if (!_pendingFileContent) {
|
||||||
|
_pendingFileContent = std::make_unique<QTemporaryFile>(TEMPORARY_CONTENT_FILEPATH);
|
||||||
|
}
|
||||||
|
if (!_pendingFileContent->open()) {
|
||||||
|
_pendingFileContent = nullptr;
|
||||||
|
connection->respond(HTTPConnection::StatusCode400);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_pendingFileContent->seek(_pendingFileContent->size());
|
||||||
|
_pendingFileContent->write(dataChunk);
|
||||||
|
_pendingFileContent->close();
|
||||||
|
|
||||||
|
// Respond immediately - will timeout if we wait for restore.
|
||||||
connection->respond(HTTPConnection::StatusCode200);
|
connection->respond(HTTPConnection::StatusCode200);
|
||||||
_pendingUploadedContent.clear();
|
if (itemName == "restore-file-chunk-final" || itemName == "restore-file") {
|
||||||
} else if (filename.endsWith(".zip", Qt::CaseInsensitive)) {
|
auto deferred = makePromise("recoverFromUploadedBackup");
|
||||||
auto deferred = makePromise("recoverFromUploadedBackup");
|
|
||||||
|
|
||||||
QPointer<HTTPConnection> connectionPtr(connection);
|
deferred->then([this](QString error, QVariantMap result) {
|
||||||
const QString JSON_MIME_TYPE = "application/json";
|
_pendingFileContent = nullptr;
|
||||||
deferred->then([connectionPtr, JSON_MIME_TYPE, this](QString error, QVariantMap result) {
|
});
|
||||||
if (!connectionPtr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject rootJSON;
|
_contentManager->recoverFromUploadedFile(deferred, _pendingFileContent->fileName());
|
||||||
auto success = result["success"].toBool();
|
} else {
|
||||||
rootJSON["success"] = success;
|
}
|
||||||
QJsonDocument docJSON(rootJSON);
|
} else if (filename.endsWith(".json", Qt::CaseInsensitive)
|
||||||
connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(),
|
|| filename.endsWith(".json.gz", Qt::CaseInsensitive)) {
|
||||||
JSON_MIME_TYPE.toUtf8());
|
_pendingUploadedContent += dataChunk;
|
||||||
|
connection->respond(HTTPConnection::StatusCode200);
|
||||||
|
|
||||||
|
if (itemName == "restore-file-chunk-final" || itemName == "restore-file") {
|
||||||
|
// invoke our method to hand the new octree file off to the octree server
|
||||||
|
QMetaObject::invokeMethod(this, "handleOctreeFileReplacement",
|
||||||
|
Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent));
|
||||||
_pendingUploadedContent.clear();
|
_pendingUploadedContent.clear();
|
||||||
});
|
}
|
||||||
|
} else {
|
||||||
_contentManager->recoverFromUploadedBackup(deferred, _pendingUploadedContent);
|
connection->respond(HTTPConnection::StatusCode400);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPSConnection* DomainServer::connectionFromReplyWithState(QNetworkReply* reply) {
|
HTTPSConnection* DomainServer::connectionFromReplyWithState(QNetworkReply* reply) {
|
||||||
|
|
|
@ -209,7 +209,7 @@ private:
|
||||||
|
|
||||||
HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply);
|
HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply);
|
||||||
|
|
||||||
void readPendingContent(HTTPConnection* connection, QString filename);
|
bool processPendingContent(HTTPConnection* connection, QString itemName, QString filename, QByteArray dataChunk);
|
||||||
|
|
||||||
bool forwardMetaverseAPIRequest(HTTPConnection* connection,
|
bool forwardMetaverseAPIRequest(HTTPConnection* connection,
|
||||||
const QString& metaversePath,
|
const QString& metaversePath,
|
||||||
|
@ -284,6 +284,7 @@ private:
|
||||||
QHash<QUuid, QPointer<HTTPSConnection>> _pendingOAuthConnections;
|
QHash<QUuid, QPointer<HTTPSConnection>> _pendingOAuthConnections;
|
||||||
|
|
||||||
QByteArray _pendingUploadedContent;
|
QByteArray _pendingUploadedContent;
|
||||||
|
std::unique_ptr<QTemporaryFile> _pendingFileContent;
|
||||||
|
|
||||||
QThread _assetClientThread;
|
QThread _assetClientThread;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue