mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
When syncing, disable event notifier and start accumulating them
until the sync is done. When they are enabled again, a forced event is scheduled to empty the queue.
This commit is contained in:
parent
64e4d531b3
commit
6b8589f4dc
6 changed files with 102 additions and 18 deletions
|
@ -53,11 +53,14 @@ void Folder::slotOpenFolder()
|
|||
|
||||
void Folder::slotSyncStarted()
|
||||
{
|
||||
// disable events until syncing is done
|
||||
_watcher->setEventsEnabled(false);
|
||||
_openAction->setIcon(QIcon(FOLDER_SYNC_ICON));
|
||||
}
|
||||
|
||||
void Folder::slotSyncFinished()
|
||||
{
|
||||
_watcher->setEventsEnabled(true);
|
||||
_openAction->setIcon(QIcon(FOLDER_ICON));
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,14 @@ public:
|
|||
*/
|
||||
virtual void startSync(const QStringList &pathList) = 0;
|
||||
|
||||
virtual bool isSyncing() const = 0;
|
||||
/**
|
||||
* True if the folder is busy and can't initiate
|
||||
* a synchronization
|
||||
*/
|
||||
virtual bool isBusy() const = 0;
|
||||
|
||||
signals:
|
||||
|
||||
void syncStarted();
|
||||
void syncFinished();
|
||||
|
||||
|
@ -44,8 +49,13 @@ private:
|
|||
QString _path;
|
||||
FolderWatcher *_watcher;
|
||||
QAction *_openAction;
|
||||
private slots:
|
||||
QStringList _pendingPaths;
|
||||
protected slots:
|
||||
|
||||
/* called when the watcher detect a list of changed
|
||||
paths */
|
||||
void slotChanged(const QStringList &pathList);
|
||||
|
||||
void slotOpenFolder();
|
||||
|
||||
void slotSyncStarted();
|
||||
|
|
|
@ -19,13 +19,15 @@ static const uint32_t standard_event_mask =
|
|||
|
||||
/* minimum amount of seconds between two
|
||||
events to consider it a new event */
|
||||
#define MIN_EVENT_INTERVAL_SEC 5
|
||||
#define DEFAULT_EVENT_INTERVAL_SEC 5
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
|
||||
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
|
||||
: QObject(parent),
|
||||
_eventsEnabled(true),
|
||||
_eventInterval(DEFAULT_EVENT_INTERVAL_SEC),
|
||||
_root(root),
|
||||
_processTimer(new QTimer(this)),
|
||||
_lastEventTime(QTime::currentTime())
|
||||
|
@ -49,6 +51,40 @@ QString FolderWatcher::root() const
|
|||
return _root;
|
||||
}
|
||||
|
||||
bool FolderWatcher::eventsEnabled() const
|
||||
{
|
||||
return _eventsEnabled;
|
||||
}
|
||||
|
||||
void FolderWatcher::setEventsEnabled(bool enabled)
|
||||
{
|
||||
_eventsEnabled = enabled;
|
||||
if (_eventsEnabled) {
|
||||
// schedule a queue cleanup for accumulated events
|
||||
if ( _pendingPaths.empty() )
|
||||
return;
|
||||
|
||||
if (!_processTimer->isActive())
|
||||
_processTimer->start(eventInterval() * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are disabling events, clear any ongoing timer
|
||||
if (_processTimer->isActive())
|
||||
_processTimer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
int FolderWatcher::eventInterval() const
|
||||
{
|
||||
return _eventInterval;
|
||||
}
|
||||
|
||||
void FolderWatcher::setEventInterval(int seconds)
|
||||
{
|
||||
_eventInterval = seconds;
|
||||
}
|
||||
|
||||
QStringList FolderWatcher::folders() const
|
||||
{
|
||||
return _inotify->directories();
|
||||
|
@ -104,29 +140,29 @@ void FolderWatcher::slotINotifyEvent(int mask, int cookie, const QString &path)
|
|||
qDebug() << cookie << " OTHER " << mask << " :" << path;
|
||||
}
|
||||
|
||||
_pendingPathList.append(path);
|
||||
_pendingPaths.append(path);
|
||||
|
||||
slotProcessPaths();
|
||||
|
||||
//if (!_processTimer->isActive())
|
||||
// _processTimer->start();
|
||||
}
|
||||
|
||||
void FolderWatcher::slotProcessPaths()
|
||||
{
|
||||
QTime eventTime = QTime::currentTime();
|
||||
|
||||
if (_lastEventTime.secsTo(eventTime) < MIN_EVENT_INTERVAL_SEC) {
|
||||
qDebug() << "Last event happened less than " << MIN_EVENT_INTERVAL_SEC << " seconds ago...";
|
||||
if (!eventsEnabled())
|
||||
return;
|
||||
|
||||
if (_lastEventTime.secsTo(eventTime) < eventInterval()) {
|
||||
qDebug() << "Last event happened less than " << eventInterval() << " seconds ago...";
|
||||
// schedule a forced queue cleanup later
|
||||
if (!_processTimer->isActive())
|
||||
_processTimer->start(MIN_EVENT_INTERVAL_SEC * 1000);
|
||||
_processTimer->start(eventInterval() * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
_lastEventTime = eventTime;
|
||||
QStringList notifyPaths(_pendingPathList);
|
||||
_pendingPathList.clear();
|
||||
QStringList notifyPaths(_pendingPaths);
|
||||
_pendingPaths.clear();
|
||||
|
||||
emit folderChanged(notifyPaths);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,31 @@ public:
|
|||
*/
|
||||
QString root() const;
|
||||
|
||||
/**
|
||||
* If true, folderChanged() events are sent
|
||||
* at least as often as eventInterval() seconds.
|
||||
*/
|
||||
bool eventsEnabled() const;
|
||||
|
||||
/**
|
||||
* Enabled or disables folderChanged() events.
|
||||
* If disabled, events are accumulated and emptied
|
||||
* the next time a folderChanged() event happens.
|
||||
*/
|
||||
void setEventsEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* The minimum amounts of seconds that will separate
|
||||
* folderChanged() intervals
|
||||
*/
|
||||
int eventInterval() const;
|
||||
|
||||
/**
|
||||
* Sets minimum amounts of seconds that will separate
|
||||
* folderChanged() intervals
|
||||
*/
|
||||
void setEventInterval(int seconds);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Emitted when one of the paths is changed
|
||||
|
@ -53,10 +78,12 @@ protected slots:
|
|||
void slotAddFolderRecursive(const QString &path);
|
||||
void slotProcessPaths();
|
||||
private:
|
||||
bool _eventsEnabled;
|
||||
int _eventInterval;
|
||||
INotify *_inotify;
|
||||
QString _root;
|
||||
// paths pending to notified
|
||||
QStringList _pendingPathList;
|
||||
QStringList _pendingPaths;
|
||||
QTimer *_processTimer;
|
||||
QTime _lastEventTime;
|
||||
};
|
||||
|
|
|
@ -22,15 +22,18 @@ UnisonFolder::UnisonFolder(const QString &path, const QString &secondPath, QObje
|
|||
|
||||
QObject::connect(_unison, SIGNAL(error(QProcess::ProcessError)),
|
||||
SLOT(slotError(QProcess::ProcessError)));
|
||||
|
||||
QObject::connect(_unison, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||
SLOT(slotFinished(int, QProcess::ExitStatus)));
|
||||
}
|
||||
|
||||
UnisonFolder::~UnisonFolder()
|
||||
{
|
||||
}
|
||||
|
||||
bool UnisonFolder::isSyncing() const
|
||||
bool UnisonFolder::isBusy() const
|
||||
{
|
||||
return false;
|
||||
return (_unison->state() != QProcess::NotRunning);
|
||||
}
|
||||
|
||||
QString UnisonFolder::secondPath() const
|
||||
|
@ -42,6 +45,8 @@ void UnisonFolder::startSync(const QStringList &pathList)
|
|||
{
|
||||
QMutexLocker locker(&_syncMutex);
|
||||
|
||||
emit syncStarted();
|
||||
|
||||
QString program = "unison";
|
||||
QStringList args;
|
||||
args << "-ui" << "text";
|
||||
|
@ -57,10 +62,11 @@ void UnisonFolder::startSync(const QStringList &pathList)
|
|||
args << path();
|
||||
args << secondPath();
|
||||
|
||||
emit syncStarted();
|
||||
|
||||
_unison->start(program, args);
|
||||
}
|
||||
|
||||
void UnisonFolder::slotFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
emit syncFinished();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,13 @@ public:
|
|||
|
||||
virtual void startSync(const QStringList &pathList);
|
||||
|
||||
virtual bool isSyncing() const;
|
||||
virtual bool isBusy() const;
|
||||
|
||||
protected slots:
|
||||
void slotReadyReadStandardOutput();
|
||||
void slotReadyReadStandardError();
|
||||
void slotStateChanged(QProcess::ProcessState);
|
||||
void slotFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void slotError(QProcess::ProcessError);
|
||||
private:
|
||||
QMutex _syncMutex;
|
||||
|
|
Loading…
Reference in a new issue