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

Throttle folder status updates in general #9919

Merged
merged 3 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions changelog/unreleased/9919
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Reduce CPU load during discovery

https://github.com/owncloud/client/pull/9919
12 changes: 3 additions & 9 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ Folder::Folder(const FolderDefinition &definition,

connect(_engine.data(), &SyncEngine::aboutToRemoveAllFiles,
this, &Folder::slotAboutToRemoveAllFiles);
connect(_engine.data(), &SyncEngine::transmissionProgress, this, &Folder::slotTransmissionProgress);
connect(_engine.data(), &SyncEngine::transmissionProgress, this, [this](const ProgressInfo &pi) {
emit ProgressDispatcher::instance()->progressInfo(this, pi);
});
connect(_engine.data(), &SyncEngine::itemCompleted,
this, &Folder::slotItemCompleted);
connect(_engine.data(), &SyncEngine::newBigFolder,
Expand Down Expand Up @@ -1125,14 +1127,6 @@ void Folder::slotEmitFinishedDelayed()
}
}

// the progress comes without a folder and the valid path set. Add that here
// and hand the result over to the progress dispatcher.
void Folder::slotTransmissionProgress(const ProgressInfo &pi)
{
emit progressInfo(pi);
emit ProgressDispatcher::instance()->progressInfo(this, pi);
}

// a item is completed: count the errors and forward to the ProgressDispatcher
void Folder::slotItemCompleted(const SyncFileItemPtr &item)
{
Expand Down
2 changes: 0 additions & 2 deletions src/gui/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ class Folder : public QObject
void syncStateChange();
void syncStarted();
void syncFinished(const SyncResult &result);
void progressInfo(const ProgressInfo &progress);
void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered
void syncPausedChanged(Folder *, bool paused);
void canSyncChanged();
Expand Down Expand Up @@ -448,7 +447,6 @@ private slots:
*/
void slotSyncError(const QString &message, ErrorCategory category = ErrorCategory::Normal);

void slotTransmissionProgress(const ProgressInfo &pi);
void slotItemCompleted(const SyncFileItemPtr &);

void etagRetreived(const QByteArray &, const QDateTime &tp);
Expand Down
62 changes: 31 additions & 31 deletions src/gui/folderstatusmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ void FolderStatusModel::setAccountState(AccountStatePtr accountState)
info._checked = Qt::PartiallyChecked;
_folders << info;

connect(f, &Folder::progressInfo, this, [f, this](const ProgressInfo &info) {
slotSetProgress(info, f);
connect(ProgressDispatcher::instance(), &ProgressDispatcher::progressInfo, this, [f, this](Folder *folder, const ProgressInfo &progress) {
if (folder == f) {
slotSetProgress(progress, f);
}
});

connect(f, &Folder::newBigFolderDiscovered, this, &FolderStatusModel::slotNewBigFolder, Qt::UniqueConnection);
Expand Down Expand Up @@ -895,38 +897,36 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress, Folder *f)

auto *pi = &folder._progress;

const QVector<int> roles = { FolderStatusDelegate::SyncProgressItemString, FolderStatusDelegate::WarningCount, Qt::ToolTipRole };

switch (progress.status()) {
case ProgressInfo::None:
Q_UNREACHABLE();
case ProgressInfo::Discovery:
if (!progress._currentDiscoveredRemoteFolder.isEmpty()) {
pi->_overallSyncString = tr("Checking for changes in remote '%1'").arg(progress._currentDiscoveredRemoteFolder);
emit dataChanged(index(folderIndex), index(folderIndex), roles);
} else if (!progress._currentDiscoveredLocalFolder.isEmpty()) {
pi->_overallSyncString = tr("Checking for changes in local '%1'").arg(progress._currentDiscoveredLocalFolder);
emit dataChanged(index(folderIndex), index(folderIndex), roles);
}
break;
case ProgressInfo::Reconcile:
pi->_overallSyncString = tr("Reconciling changes");
emit dataChanged(index(folderIndex), index(folderIndex), roles);
break;
case ProgressInfo::Propagation:
Q_FALLTHROUGH();
case ProgressInfo::Done:
if (!progress._lastCompletedItem.isEmpty()
&& Progress::isWarningKind(progress._lastCompletedItem._status)) {
pi->_warningCount++;
}
if (progress.status() == ProgressInfo::Done && !progress._lastCompletedItem.isEmpty()
&& Progress::isWarningKind(progress._lastCompletedItem._status)) {
pi->_warningCount++;
}
// depending on the use of virtual files or small files this slot might be called very often.
// throttle the model updates to prevent an needlessly high cpu usage used on ui updates.
if (std::chrono::steady_clock::now() - folder._lastProgressUpdated > progressUpdateTimeOutC) {
TheOneRing marked this conversation as resolved.
Show resolved Hide resolved
const QVector<int> roles = { FolderStatusDelegate::SyncProgressItemString, FolderStatusDelegate::WarningCount, Qt::ToolTipRole };

// progress updates are expensive, throtle them
if (std::chrono::steady_clock::now() - folder._lastProgressUpdated > progressUpdateTimeOutC) {
switch (progress.status()) {
case ProgressInfo::None:
Q_UNREACHABLE();
break;
case ProgressInfo::Discovery:
if (!progress._currentDiscoveredRemoteFolder.isEmpty()) {
pi->_overallSyncString = tr("Checking for changes in remote '%1'").arg(progress._currentDiscoveredRemoteFolder);
} else if (!progress._currentDiscoveredLocalFolder.isEmpty()) {
pi->_overallSyncString = tr("Checking for changes in local '%1'").arg(progress._currentDiscoveredLocalFolder);
}
break;
case ProgressInfo::Reconcile:
pi->_overallSyncString = tr("Reconciling changes");
break;
case ProgressInfo::Propagation:
Q_FALLTHROUGH();
case ProgressInfo::Done:
computeProgress(progress, pi);
folder._lastProgressUpdated = std::chrono::steady_clock::now();
emit dataChanged(index(folderIndex), index(folderIndex), roles);
}
emit dataChanged(index(folderIndex), index(folderIndex), roles);
folder._lastProgressUpdated = std::chrono::steady_clock::now();
}
}

Expand Down