Implement an event queue:

- If FolderWatcher receives a inotify event in less than 5
  seconds from the last one, then the paths are queued and a timer
  is setup for 5 seconds more. New events are queued if a timer
  is running. The next event after the time gap is due will process
  the full path list
This commit is contained in:
Duncan Mac-Vicar P 2011-03-22 23:03:43 +01:00
parent f42169a8fc
commit d885fe39f8
7 changed files with 52 additions and 16 deletions

View File

@ -7,7 +7,7 @@
#include "mirall/constants.h"
#include "mirall/application.h"
#include "mirall/folder.h"
#include "mirall/gitfolder.h"
#include "mirall/unisonfolder.h"
#include "mirall/inotify.h"
namespace Mirall {
@ -17,7 +17,7 @@ Application::Application(int argc, char **argv) :
{
INotify::initialize();
_folder = new GitFolder(QDir::homePath() + "/Mirall", this);
_folder = new UnisonFolder(QDir::homePath() + "/Mirall", "/space/tmp/testmirall", this);
setApplicationName("Mirall");
setupActions();
setupSystemTray();

View File

@ -19,8 +19,8 @@ Folder::Folder(const QString &path, QObject *parent)
QObject::connect(_action, SIGNAL(triggered(bool)), SLOT(slotOpenFolder()));
_watcher = new Mirall::FolderWatcher(path, this);
QObject::connect(_watcher, SIGNAL(folderChanged(const QString &)),
SLOT(slotChanged(const QString &)));
QObject::connect(_watcher, SIGNAL(folderChanged(const QStringList &)),
SLOT(slotChanged(const QStringList &)));
}
Folder::~Folder()
@ -37,9 +37,10 @@ QAction * Folder::action() const
return _action;
}
void Folder::slotChanged(const QString &path)
void Folder::slotChanged(const QStringList &pathList)
{
//qDebug() << "path " << path << " changed";
qDebug() << "Changed >> " << pathList;
}
void Folder::slotOpenFolder()

View File

@ -3,6 +3,7 @@
#include <QObject>
#include <QString>
#include <QStringList>
class QAction;
@ -28,6 +29,8 @@ public:
*/
virtual void startSync() = 0;
virtual bool isSyncing() const = 0;
signals:
void syncStarted();
void syncFinished();
@ -39,7 +42,7 @@ private:
FolderWatcher *_watcher;
QAction *_action;
private slots:
void slotChanged(const QString &path);
void slotChanged(const QStringList &pathList);
void slotOpenFolder();
};

View File

@ -19,7 +19,7 @@ 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 2
#define MIN_EVENT_INTERVAL_SEC 5
namespace Mirall {
@ -27,8 +27,12 @@ namespace Mirall {
FolderWatcher::FolderWatcher(const QString &root, QObject *parent)
: QObject(parent),
_root(root),
_processTimer(new QTimer(this)),
_lastEventTime(QTime::currentTime())
{
_processTimer->setSingleShot(true);
QObject::connect(_processTimer, SIGNAL(timeout()), this, SLOT(slotProcessPaths()));
_inotify = new INotify(standard_event_mask);
slotAddFolderRecursive(root);
QObject::connect(_inotify, SIGNAL(notifyEvent(int, int, const QString &)),
@ -70,9 +74,6 @@ void FolderWatcher::slotAddFolderRecursive(const QString &path)
void FolderWatcher::slotINotifyEvent(int mask, int cookie, const QString &path)
{
QMutexLocker locker(&_mutex);
QTime eventTime = QTime::currentTime();
if (IN_IGNORED & mask) {
qDebug() << "IGNORE event";
return;
@ -103,16 +104,36 @@ void FolderWatcher::slotINotifyEvent(int mask, int cookie, const QString &path)
qDebug() << cookie << " OTHER " << mask << " :" << path;
}
_pendingPathList.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 2 seconds ago...";
qDebug() << "Last event happened less than " << MIN_EVENT_INTERVAL_SEC << " seconds ago...";
// schedule a forced queue cleanup later
if (!_processTimer->isActive())
_processTimer->start(MIN_EVENT_INTERVAL_SEC * 1000);
return;
}
_lastEventTime = eventTime;
QStringList notifyPaths(_pendingPathList);
_pendingPathList.clear();
emit folderChanged(path);
emit folderChanged(notifyPaths);
}
}
#include "folderwatcher.moc"

View File

@ -4,10 +4,11 @@
#define MIRALL_FOLDERWATCHER_H
#include <QObject>
#include <QMutex>
#include <QString>
#include <QStringList>
#include <QTime>
class QTimer;
class INotify;
namespace Mirall {
@ -39,15 +40,18 @@ signals:
/**
* Emitted when one of the paths is changed
*/
void folderChanged(const QString &path);
void folderChanged(const QStringList &pathList);
protected slots:
void slotINotifyEvent(int mask, int cookie, const QString &path);
void slotAddFolderRecursive(const QString &path);
void slotProcessPaths();
private:
QMutex _mutex;
INotify *_inotify;
QString _root;
// paths pending to notified
QStringList _pendingPathList;
QTimer *_processTimer;
QTime _lastEventTime;
};

View File

@ -16,6 +16,11 @@ UnisonFolder::~UnisonFolder()
{
}
bool UnisonFolder::isSyncing() const
{
return false;
}
QString UnisonFolder::secondPath() const
{
return _secondPath;

View File

@ -18,6 +18,8 @@ public:
virtual void startSync();
virtual bool isSyncing() const;
private:
QMutex _syncMutex;
QProcess *_unison;