diff options
author | Klaas Freitag <freitag@owncloud.com> | 2012-02-28 19:49:13 +0400 |
---|---|---|
committer | Klaas Freitag <freitag@owncloud.com> | 2012-02-28 19:49:13 +0400 |
commit | f6846a2107862a058ce608ad6fd5dc2cd71593d8 (patch) | |
tree | f8f349dbebbe27e6acfbdc1182a0aa9d88fae557 | |
parent | 59b8af2aefee5ea81b0cd0e0c68a019de88d173b (diff) |
Added local polling to owncloud folder, based on csync.
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/mirall/csyncthread.cpp | 79 | ||||
-rw-r--r-- | src/mirall/csyncthread.h | 8 | ||||
-rw-r--r-- | src/mirall/folder.cpp | 26 | ||||
-rw-r--r-- | src/mirall/folder.h | 11 | ||||
-rw-r--r-- | src/mirall/folderman.cpp | 7 | ||||
-rw-r--r-- | src/mirall/owncloudfolder.cpp | 51 | ||||
-rw-r--r-- | src/mirall/owncloudfolder.h | 11 |
8 files changed, 167 insertions, 30 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 76e1305b9..9d37fff86 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,9 @@ include_directories(${CMAKE_SOURCE_DIR}/src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libqtwebdav) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../csync/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../csync/src) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../buildcsync/src) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../buildcsync/src) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include(${QT_USE_FILE}) diff --git a/src/mirall/csyncthread.cpp b/src/mirall/csyncthread.cpp index 27c3b41bd..d5b944ba8 100644 --- a/src/mirall/csyncthread.cpp +++ b/src/mirall/csyncthread.cpp @@ -19,16 +19,21 @@ #include <QThread> #include <QStringList> #include <QTextStream> +#include <QTime> #include <csync.h> + #include "mirall/csyncthread.h" namespace Mirall { -CSyncThread::CSyncThread(const QString &source, const QString &target) +CSyncThread::CSyncThread(const QString &source, const QString &target, bool localCheckOnly) : _source(source) , _target(target) + , _localCheckOnly( localCheckOnly ) , _error(0) + , _localChanges(false) + , _walkedFiles(-1) { } @@ -56,27 +61,89 @@ void CSyncThread::run() _target.toLocal8Bit().data()); if (error()) return; + qDebug() << "## CSync Thread local only: " << _localCheckOnly; #if LIBCSYNC_VERSION_INT >= CSYNC_VERSION_INT(0, 45, 0) csync_enable_conflictcopys(csync); #endif - _error = csync_init(csync); + QTime t; + t.start(); + + if( _localCheckOnly ) { + _error = csync_set_local_only( csync, true ); + if(error()) + goto cleanup; + } + _error = csync_init(csync); if (error()) goto cleanup; + qDebug() << "############################################################### >>"; _error = csync_update(csync); + qDebug() << "<<###############################################################"; if (error()) goto cleanup; - _error = csync_reconcile(csync); - if (error()) - goto cleanup; - _error = csync_propagate(csync); + + UPDATE_METRICS met; + met.filesUpdated = 0; + met.filesNew = 0; + met.filesWalked = 0; + + csync_update_metrics( csync, &met ); + + qDebug() << "New files: " << met.filesNew; + qDebug() << "Updated files: " << met.filesUpdated; + qDebug() << "Walked files: " << met.filesWalked; + + _walkedFiles = met.filesWalked; + + if( _localCheckOnly ) { + if( met.filesNew + met.filesUpdated > 0 ) { + _localChanges = true; + + qDebug() << "OO there are local changes!"; + } + // we have to go out here as its local check only. + goto cleanup; + } else { + _error = csync_reconcile(csync); + if (error()) + goto cleanup; + + _error = csync_propagate(csync); + _localChanges = false; + } cleanup: csync_destroy(csync); + qDebug() << "CSync run took " << t.elapsed() << " Milliseconds"; +} + +int64_t CSyncThread::walkedFiles() +{ + return _walkedFiles; +} + +bool CSyncThread::hasLocalChanges( int64_t prevWalked ) const +{ + if( _localChanges ) return true; + + if( _walkedFiles == -1 || prevWalked == -1 ) { // we don't know how + return false; + } else { + if( prevWalked < _walkedFiles ) { + qDebug() << "Files were added!"; + return true; + } else if( prevWalked > _walkedFiles ){ + qDebug() << "Files were removed!"; + return true; + } else { + return false; + } + } } } diff --git a/src/mirall/csyncthread.h b/src/mirall/csyncthread.h index ffdc1ef70..fa777a91d 100644 --- a/src/mirall/csyncthread.h +++ b/src/mirall/csyncthread.h @@ -27,7 +27,7 @@ namespace Mirall { class CSyncThread : public QThread { public: - CSyncThread(const QString &source, const QString &target); + CSyncThread(const QString &source, const QString &target, bool = false); ~CSyncThread(); virtual void run(); @@ -37,11 +37,17 @@ public: */ bool error() const; + bool hasLocalChanges( int64_t ) const; + int64_t walkedFiles(); + private: static QMutex _mutex; QString _source; QString _target; int _error; + bool _localCheckOnly; + bool _localChanges; + int64_t _walkedFiles; }; } diff --git a/src/mirall/folder.cpp b/src/mirall/folder.cpp index e6f2560e1..71dcc1b7e 100644 --- a/src/mirall/folder.cpp +++ b/src/mirall/folder.cpp @@ -20,7 +20,7 @@ #include "mirall/folder.h" #include "mirall/folderwatcher.h" -#define DEFAULT_POLL_INTERVAL_SEC 15 +#define DEFAULT_POLL_INTERVAL_SEC 15000 namespace Mirall { @@ -29,7 +29,6 @@ Folder::Folder(const QString &alias, const QString &path, QObject *parent) _errorCount(0), _path(path), _pollTimer(new QTimer(this)), - _pollInterval(DEFAULT_POLL_INTERVAL_SEC), _alias(alias), _onlyOnlineEnabled(false), _onlyThisLANEnabled(false), @@ -37,14 +36,16 @@ Folder::Folder(const QString &alias, const QString &path, QObject *parent) _enabled(true) { _pollTimer->setSingleShot(true); - _pollTimer->setInterval(pollInterval() * 1000); + _pollTimer->setInterval( DEFAULT_POLL_INTERVAL_SEC ); + QObject::connect(_pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerTimeout())); _pollTimer->start(); +#ifdef USE_WATCHER _watcher = new Mirall::FolderWatcher(path, this); QObject::connect(_watcher, SIGNAL(folderChanged(const QStringList &)), SLOT(slotChanged(const QStringList &))); - +#endif QObject::connect(this, SIGNAL(syncStarted()), SLOT(slotSyncStarted())); QObject::connect(this, SIGNAL(syncFinished(const SyncResult &)), @@ -79,7 +80,9 @@ bool Folder::syncEnabled() const void Folder::setSyncEnabled( bool doit ) { _enabled = doit; +#ifdef USE_WATCHER _watcher->setEventsEnabled( doit ); +#endif } bool Folder::onlyOnlineEnabled() const @@ -104,12 +107,12 @@ void Folder::setOnlyThisLANEnabled(bool enabled) int Folder::pollInterval() const { - return _pollInterval; + return _pollTimer->interval(); } -void Folder::setPollInterval(int seconds) +void Folder::setPollInterval(int milliseconds) { - _pollInterval = seconds; + _pollTimer->setInterval( milliseconds ); } int Folder::errorCount() @@ -128,10 +131,12 @@ void Folder::incrementErrorCount() // of the watcher is doubled. _errorCount++; if( _errorCount > 1 ) { +#ifdef USE_WATCHER int interval = _watcher->eventInterval(); int newInt = 2*interval; qDebug() << "Set new watcher interval to " << newInt; _watcher->setEventInterval( newInt ); +#endif _errorCount = 0; } } @@ -151,13 +156,16 @@ void Folder::evaluateSync(const QStringList &pathList) qDebug() << "*" << alias() << "sync skipped, not online"; return; } - startSync(pathList); + + startSync( pathList ); } void Folder::slotPollTimerTimeout() { qDebug() << "* Polling" << alias() << "for changes. Ignoring all pending events until now"; +#ifdef USE_WATCHER _watcher->clearPendingEvents(); +#endif qDebug() << "* " << alias() << "Poll timer disabled"; _pollTimer->stop(); evaluateSync(QStringList()); @@ -178,7 +186,9 @@ void Folder::slotChanged(const QStringList &pathList) void Folder::slotSyncStarted() { // disable events until syncing is done +#ifdef USE_WATCHER _watcher->setEventsEnabled(false); +#endif _syncResult = SyncResult( SyncResult::SyncRunning ); emit syncStateChange(); diff --git a/src/mirall/folder.h b/src/mirall/folder.h index 8a07b16c1..62db681d4 100644 --- a/src/mirall/folder.h +++ b/src/mirall/folder.h @@ -124,6 +124,7 @@ public: QString backend() const; QIcon icon( int size ) const; + QTimer *_pollTimer; public slots: void slotSyncFinished(const SyncResult &); @@ -137,10 +138,10 @@ protected: int pollInterval() const; /** - * Sets minimum amounts of seconds that will separate + * Sets minimum amounts of milliseconds that will separate * poll intervals */ - void setPollInterval(int seconds); + void setPollInterval( int ); signals: void syncStateChange(); @@ -148,9 +149,12 @@ signals: void syncFinished(const SyncResult &result); protected: +#ifdef USE_WATCHER FolderWatcher *_watcher; +#endif int _errorCount; + private: /** @@ -161,8 +165,7 @@ private: QString _path; // poll timer for remote syncs - QTimer *_pollTimer; - int _pollInterval; + QString _alias; bool _onlyOnlineEnabled; bool _onlyThisLANEnabled; diff --git a/src/mirall/folderman.cpp b/src/mirall/folderman.cpp index bec63fdcd..1043e2d44 100644 --- a/src/mirall/folderman.cpp +++ b/src/mirall/folderman.cpp @@ -58,16 +58,17 @@ Mirall::Folder::Map FolderMan::map() int FolderMan::setupFolders() { // setup a handler to look for configuration changes +#ifdef CHECK_FOR_SETUP_CHANGES _configFolderWatcher = new FolderWatcher( _folderConfigPath ); - _configFolderWatcher->setEventInterval(200); + _configFolderWatcher->setEventInterval(20000); connect(_configFolderWatcher, SIGNAL(folderChanged(const QStringList &)), this, SLOT( slotReparseConfiguration()) ); - +#endif int cnt = setupKnownFolders(); // do an initial sync foreach( Folder *f, _folderMap.values() ) { - f->slotChanged(); + // f->slotChanged(); } return cnt; } diff --git a/src/mirall/owncloudfolder.cpp b/src/mirall/owncloudfolder.cpp index 4682bc8fc..86bcdf1e4 100644 --- a/src/mirall/owncloudfolder.cpp +++ b/src/mirall/owncloudfolder.cpp @@ -20,6 +20,7 @@ #include <QThread> #include <QStringList> #include <QTextStream> +#include <QTimer> #include "csync.h" @@ -33,15 +34,35 @@ ownCloudFolder::ownCloudFolder(const QString &alias, QObject *parent) : Folder(alias, path, parent) , _secondPath(secondPath) + , _localCheckOnly( false ) , _csync(0) + , _pollTimerCnt(0) + , _lastWalkedFiles(-1) + { + connect( _pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerRemoteCheck())); + qDebug() << "****** connect ownCloud Timer"; + // set a local poll time of 2000 milliseconds, which results in a 30 seconds + // remote poll interval, defined in slotPollTimerRemoteCheck + setPollInterval( 2000 ); } ownCloudFolder::~ownCloudFolder() { } +void ownCloudFolder::slotPollTimerRemoteCheck() +{ + _localCheckOnly = true; + _pollTimerCnt++; + if( _pollTimerCnt == 15 ) { + _pollTimerCnt = 0; + _localCheckOnly = false; + } + qDebug() << "**** CSyncFolder Poll Timer check: " << _pollTimerCnt << " - " << _localCheckOnly; +} + bool ownCloudFolder::isBusy() const { return false; @@ -52,6 +73,11 @@ QString ownCloudFolder::secondPath() const return _secondPath; } +void ownCloudFolder::startSync() +{ + startSync( QStringList() ); +} + void ownCloudFolder::startSync(const QStringList &pathList) { if (_csync && _csync->isRunning()) { @@ -63,10 +89,10 @@ void ownCloudFolder::startSync(const QStringList &pathList) /* Fix the url and remove user and password */ QUrl url( _secondPath ); url.setScheme( "owncloud" ); - qDebug() << "*** Start syncing to ownCloud"; + qDebug() << "*** Start syncing to ownCloud, onlyLocal: " << _localCheckOnly; - _csync = new CSyncThread(path(), url.toEncoded() ); - QObject::connect(_csync, SIGNAL(started()), SLOT(slotCSyncStarted())); + _csync = new CSyncThread(path(), url.toEncoded(), _localCheckOnly ); + QObject::connect(_csync, SIGNAL(started()), SLOT(slotCSyncStarted())); QObject::connect(_csync, SIGNAL(finished()), SLOT(slotCSyncFinished())); _csync->start(); } @@ -80,14 +106,25 @@ void ownCloudFolder::slotCSyncStarted() void ownCloudFolder::slotCSyncFinished() { if (_csync->error()) - qDebug() << " * csync thread finished with error"; + qDebug() << " * owncloud csync thread finished with error"; else - qDebug() << " * csync thread finished successfully"; - + qDebug() << " * owncloud csync thread finished successfully"; + + if( _csync->hasLocalChanges( _lastWalkedFiles ) ) { + qDebug() << "Last walked files: " << _lastWalkedFiles << " against " << _csync->walkedFiles(); + qDebug() << "*** Local changes, lets do a full sync!" ; + _localCheckOnly = false; + _pollTimerCnt = 0; + _lastWalkedFiles = -1; + QTimer::singleShot( 0, this, SLOT(startSync( QStringList() ))); + } else { + qDebug() << " *** Finalize, pollTimerCounter is "<< _pollTimerCnt ; + _lastWalkedFiles = _csync->walkedFiles(); // TODO delete thread - emit syncFinished(_csync->error() ? + emit syncFinished(_csync->error() ? SyncResult(SyncResult::Error) : SyncResult(SyncResult::Success)); + } } } // ns diff --git a/src/mirall/owncloudfolder.h b/src/mirall/owncloudfolder.h index b3b9ee73a..6b13b3d65 100644 --- a/src/mirall/owncloudfolder.h +++ b/src/mirall/owncloudfolder.h @@ -36,14 +36,23 @@ public: const QString &secondPath, QObject *parent = 0L); virtual ~ownCloudFolder(); QString secondPath() const; - virtual void startSync(const QStringList &pathList); virtual bool isBusy() const; + virtual void startSync(const QStringList &pathList); + +public slots: + void startSync(); + protected slots: void slotCSyncStarted(); void slotCSyncFinished(); + void slotPollTimerRemoteCheck(); + private: QString _secondPath; CSyncThread *_csync; + bool _localCheckOnly; + int _pollTimerCnt; + int64_t _lastWalkedFiles; }; } |