Skip to content

Commit

Permalink
Throttle ui updates
Browse files Browse the repository at this point in the history
Issue: #9832
  • Loading branch information
TheOneRing committed Jul 6, 2022
1 parent 2b8235a commit 5409b20
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 36 deletions.
6 changes: 4 additions & 2 deletions changelog/unreleased/9832
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Enhancement: Run vfs downloads with a high priority
Enhancement: Throttle the UI updates during sync

This should reduce the occurance of timeouts when downloading vfs files in the Windows explorer.
We reduced the number of UI updates during the sync,
especially with Windows vfs files this should improve the performance by a lot.

https://github.com/owncloud/client/issues/9832
https://github.com/owncloud/client/pull/9863
6 changes: 6 additions & 0 deletions changelog/unreleased/9836
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Run vfs downloads with a high priority

This should reduce the occurance of timeouts when downloading vfs files in the Windows explorer.

https://github.com/owncloud/client/pull/9836
https://github.com/owncloud/client/issues/9832
74 changes: 41 additions & 33 deletions src/gui/folderstatusmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@
#include <QVarLengthArray>
#include <set>

using namespace std::chrono_literals;

Q_DECLARE_METATYPE(QPersistentModelIndex)

namespace OCC {

Q_LOGGING_CATEGORY(lcFolderStatus, "gui.folder.model", QtInfoMsg)

static const char propertyParentIndexC[] = "oc_parentIndex";
static const char propertyPermissionMap[] = "oc_permissionMap";
namespace {
// minimum delay between progress updates
constexpr auto progressUpdateTimeOutC = 1s;

const char propertyParentIndexC[] = "oc_parentIndex";
const char propertyPermissionMap[] = "oc_permissionMap";
}

static QString removeTrailingSlash(const QString &s)
{
Expand Down Expand Up @@ -84,7 +91,10 @@ void FolderStatusModel::setAccountState(const AccountState *accountState)
info._checked = Qt::PartiallyChecked;
_folders << info;

connect(f, &Folder::progressInfo, this, &FolderStatusModel::slotSetProgress, Qt::UniqueConnection);
connect(f, &Folder::progressInfo, this, [f, this](const ProgressInfo &info) {
slotSetProgress(info, f);
});

connect(f, &Folder::newBigFolderDiscovered, this, &FolderStatusModel::slotNewBigFolder, Qt::UniqueConnection);
}

Expand Down Expand Up @@ -863,61 +873,60 @@ void FolderStatusModel::slotApplySelectiveSync()
resetFolders();
}

void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
void FolderStatusModel::slotSetProgress(const ProgressInfo &progress, Folder *f)
{
auto par = qobject_cast<QWidget *>(QObject::parent());
if (!par->isVisible()) {
if (!qobject_cast<QWidget *>(QObject::parent())->isVisible()) {
return; // for https://github.com/owncloud/client/issues/2648#issuecomment-71377909
}

Folder *f = qobject_cast<Folder *>(sender());
if (!f) {
return;
}

int folderIndex = -1;
for (int i = 0; i < _folders.count(); ++i) {
if (_folders.at(i)._folder == f) {
folderIndex = i;
break;
const int folderIndex = [f, this] {
int folderIndex = -1;
for (int i = 0; i < _folders.count(); ++i) {
if (_folders.at(i)._folder == f) {
folderIndex = i;
break;
}
}
}
return folderIndex;
}();
if (folderIndex < 0) {
return;
}

auto *pi = &_folders[folderIndex]._progress;

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

if (progress.status() == 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);
return;
} else if (!progress._currentDiscoveredLocalFolder.isEmpty()) {
pi->_overallSyncString = tr("Checking for changes in local '%1'").arg(progress._currentDiscoveredLocalFolder);
emit dataChanged(index(folderIndex), index(folderIndex), roles);
return;
}
}

if (progress.status() == ProgressInfo::Reconcile) {
} else if (progress.status() == ProgressInfo::Reconcile) {
pi->_overallSyncString = tr("Reconciling changes");
emit dataChanged(index(folderIndex), index(folderIndex), roles);
return;
}
} else {
// Status is Starting, Propagation or Done

// Status is Starting, Propagation or Done
if (!progress._lastCompletedItem.isEmpty()
&& Progress::isWarningKind(progress._lastCompletedItem._status)) {
pi->_warningCount++;
}

if (!progress._lastCompletedItem.isEmpty()
&& Progress::isWarningKind(progress._lastCompletedItem._status)) {
pi->_warningCount++;
// progress updates are expensive, throtle them
if (std::chrono::steady_clock::now() - _lastProgressUpdated > progressUpdateTimeOutC) {
computeProgress(progress, pi);
_lastProgressUpdated = std::chrono::steady_clock::now();
emit dataChanged(index(folderIndex), index(folderIndex), roles);
}
}
}

void FolderStatusModel::computeProgress(const ProgressInfo &progress, SubFolderInfo::Progress *pi)
{
// find the single item to display: This is going to be the bigger item, or the last completed
// item if no items are in progress.
SyncFileItem curItem = progress._lastCompletedItem;
Expand Down Expand Up @@ -1039,7 +1048,6 @@ void FolderStatusModel::slotSetProgress(const ProgressInfo &progress)
overallPercent = qRound(double(completedSize + completedFile) / double(totalSize + totalFileCount) * 100.0);
}
pi->_overallPercent = qBound(0, overallPercent, 100);
emit dataChanged(index(folderIndex), index(folderIndex), roles);
}

void FolderStatusModel::slotFolderSyncStateChange(Folder *f)
Expand Down
6 changes: 5 additions & 1 deletion src/gui/folderstatusmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public slots:
void resetFolders();
void slotSyncAllPendingBigFolders();
void slotSyncNoPendingBigFolders();
void slotSetProgress(const ProgressInfo &progress);
void slotSetProgress(const ProgressInfo &progress, Folder *f);

private slots:
void slotUpdateDirectories(const QStringList &);
Expand All @@ -155,8 +155,12 @@ private slots:
private:
QStringList createBlackList(const OCC::FolderStatusModel::SubFolderInfo &root,
const QStringList &oldBlackList) const;

void computeProgress(const ProgressInfo &progress, SubFolderInfo::Progress *pi);

const AccountState *_accountState;
bool _dirty; // If the selective sync checkboxes were changed
std::chrono::steady_clock::time_point _lastProgressUpdated = std::chrono::steady_clock::now();

/**
* Keeps track of items that are fetching data from the server.
Expand Down

0 comments on commit 5409b20

Please sign in to comment.