Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for server chunked file upload V2 API #5939

Merged
merged 17 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/common/syncjournaldb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file)

if (query->next().hasData) {
bool ok = true;
res._chunk = query->intValue(0);
res._chunkUploadV1 = query->intValue(0);
res._transferid = query->int64Value(1);
res._errorCount = query->intValue(2);
res._size = query->int64Value(3);
Expand Down Expand Up @@ -1678,7 +1678,7 @@ void SyncJournalDb::setUploadInfo(const QString &file, const SyncJournalDb::Uplo
}

query->bindValue(1, file);
query->bindValue(2, i._chunk);
query->bindValue(2, i._chunkUploadV1);
query->bindValue(3, i._transferid);
query->bindValue(4, i._errorCount);
query->bindValue(5, i._size);
Expand Down Expand Up @@ -2714,13 +2714,8 @@ bool operator==(const SyncJournalDb::DownloadInfo &lhs,
bool operator==(const SyncJournalDb::UploadInfo &lhs,
const SyncJournalDb::UploadInfo &rhs)
{
return lhs._errorCount == rhs._errorCount
&& lhs._chunk == rhs._chunk
&& lhs._modtime == rhs._modtime
&& lhs._valid == rhs._valid
&& lhs._size == rhs._size
&& lhs._transferid == rhs._transferid
&& lhs._contentChecksum == rhs._contentChecksum;
return lhs._errorCount == rhs._errorCount && lhs._chunkUploadV1 == rhs._chunkUploadV1 && lhs._modtime == rhs._modtime && lhs._valid == rhs._valid
&& lhs._size == rhs._size && lhs._transferid == rhs._transferid && lhs._contentChecksum == rhs._contentChecksum;
}

QDebug& operator<<(QDebug &stream, const SyncJournalFileRecord::EncryptionStatus status)
Expand Down
2 changes: 1 addition & 1 deletion src/common/syncjournaldb.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject
};
struct UploadInfo
{
int _chunk = 0;
int _chunkUploadV1 = 0;
uint _transferid = 0;
qint64 _size = 0;
qint64 _modtime = 0;
Expand Down
7 changes: 4 additions & 3 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,9 +1036,10 @@ SyncOptions Folder::initializeSyncOptions() const
opt._vfs = _vfs;
opt._parallelNetworkJobs = _accountState->account()->isHttp2Supported() ? 20 : 6;

opt._initialChunkSize = cfgFile.chunkSize();
opt._minChunkSize = cfgFile.minChunkSize();
opt._maxChunkSize = cfgFile.maxChunkSize();
// Chunk V2: Size of chunks must be between 5MB and 5GB, except for the last chunk which can be smaller
opt.setMinChunkSize(cfgFile.minChunkSize());
opt.setMaxChunkSize(cfgFile.maxChunkSize());
opt._initialChunkSize = ::qBound(opt.minChunkSize(), cfgFile.chunkSize(), opt.maxChunkSize());
opt._targetChunkUploadDuration = cfgFile.targetChunkUploadDuration();

opt.fillFromEnvironmentVariables();
Expand Down
2 changes: 1 addition & 1 deletion src/libsync/bulkpropagatorjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void BulkPropagatorJob::doStartUpload(SyncFileItemPtr item,
// in reconcile (issue #5106)
SyncJournalDb::UploadInfo pi;
pi._valid = true;
pi._chunk = 0;
pi._chunkUploadV1 = 0;
pi._transferid = 0; // We set a null transfer id because it is not chunked.
pi._modtime = item->_modtime;
pi._errorCount = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/libsync/configfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,19 +246,19 @@ int ConfigFile::timeout() const
qint64 ConfigFile::chunkSize() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(chunkSizeC), 10 * 1000 * 1000).toLongLong(); // default to 10 MB
return settings.value(QLatin1String(chunkSizeC), 10LL * 1000LL * 1000LL).toLongLong(); // default to 10 MB
}

qint64 ConfigFile::maxChunkSize() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(maxChunkSizeC), 1000 * 1000 * 1000).toLongLong(); // default to 1000 MB
return settings.value(QLatin1String(maxChunkSizeC), 5LL * 1000LL * 1000LL * 1000LL).toLongLong(); // default to 5000 MB
}

qint64 ConfigFile::minChunkSize() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(minChunkSizeC), 1000 * 1000).toLongLong(); // default to 1 MB
return settings.value(QLatin1String(minChunkSizeC), 5LL * 1000LL * 1000LL).toLongLong(); // default to 5 MB
}

chrono::milliseconds ConfigFile::targetChunkUploadDuration() const
Expand Down
3 changes: 2 additions & 1 deletion src/libsync/owncloudpropagator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,8 @@ bool OwncloudPropagator::isDelayedUploadItem(const SyncFileItemPtr &item) const
return true;
};

return account()->capabilities().bulkUpload() && !_scheduleDelayedTasks && !item->isEncrypted() && _syncOptions._minChunkSize > item->_size && !isInBulkUploadBlackList(item->_file) && !checkFileShouldBeEncrypted(item);
return account()->capabilities().bulkUpload() && !_scheduleDelayedTasks && !item->isEncrypted() && _syncOptions.minChunkSize() > item->_size
&& !isInBulkUploadBlackList(item->_file) && !checkFileShouldBeEncrypted(item);
}

void OwncloudPropagator::setScheduleDelayedTasks(bool active)
Expand Down
48 changes: 24 additions & 24 deletions src/libsync/propagateupload.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,27 +378,6 @@ private slots:
class PropagateUploadFileNG : public PropagateUploadFileCommon
{
Q_OBJECT
private:
qint64 _sent = 0; /// amount of data (bytes) that was already sent
uint _transferId = 0; /// transfer id (part of the url)
int _currentChunk = 0; /// Id of the next chunk that will be sent
qint64 _currentChunkSize = 0; /// current chunk size
bool _removeJobError = false; /// If not null, there was an error removing the job

// Map chunk number with its size from the PROPFIND on resume.
// (Only used from slotPropfindIterate/slotPropfindFinished because the LsColJob use signals to report data.)
struct ServerChunkInfo
{
qint64 size = 0LL;
QString originalName;
};
QMap<qint64, ServerChunkInfo> _serverChunks;

/**
* Return the URL of a chunk.
* If chunk == -1, returns the URL of the parent folder containing the chunks
*/
QUrl chunkUrl(int chunk = -1);

public:
PropagateUploadFileNG(OwncloudPropagator *propagator, const SyncFileItemPtr &item)
Expand All @@ -408,11 +387,9 @@ class PropagateUploadFileNG : public PropagateUploadFileCommon

void doStartUpload() override;

private:
void startNewUpload();
void startNextChunk();
public slots:
void abort(OCC::PropagateUploadFileNG::AbortType abortType) override;

private slots:
void slotPropfindFinished();
void slotPropfindFinishedWithError();
Expand All @@ -422,5 +399,28 @@ private slots:
void slotPutFinished();
void slotMoveJobFinished();
void slotUploadProgress(qint64, qint64);

private:
// Map chunk number with its size from the PROPFIND on resume.
// (Only used from slotPropfindIterate/slotPropfindFinished because the LsColJob use signals to report data.)
struct ServerChunkInfo {
qint64 size = 0LL;
QString originalName;
};

[[nodiscard]] QUrl chunkUploadFolderUrl() const;
[[nodiscard]] QUrl chunkUrl(const int chunk) const;

void startNewUpload();
void startNextChunk();
void finishUpload();

QMap<qint64, ServerChunkInfo> _serverChunks;

qint64 _sent = 0; /// amount of data (bytes) that was already sent
uint _transferId = 0; /// transfer id (part of the url)
int _currentChunk = 1; /// Id of the next chunk that will be sent
qint64 _currentChunkSize = 0; /// current chunk size
bool _removeJobError = false; /// If not null, there was an error removing the job
};
}
Loading
Loading