Remove code for local sync runs

Rely entirely on folderwatcher. Local
sync runs can be implemented in terms
of a dummy folderwatcher if we want
to support systems without fs monitoring
again..
This commit is contained in:
Daniel Molkentin 2012-12-06 17:34:12 +01:00
parent ff1706c729
commit 287c073f00
7 changed files with 12 additions and 250 deletions

View file

@ -71,95 +71,9 @@ walkStats_s::walkStats_s() {
}
int CSyncThread::recordStats( TREE_WALK_FILE* file )
{
if( ! file ) return -1;
_mutex.lock();
_walkStats.seenFiles++;
switch(file->instruction) {
case CSYNC_INSTRUCTION_NONE:
break;
case CSYNC_INSTRUCTION_EVAL:
_walkStats.eval++;
break;
case CSYNC_INSTRUCTION_REMOVE:
_walkStats.removed++;
break;
case CSYNC_INSTRUCTION_RENAME:
_walkStats.renamed++;
break;
case CSYNC_INSTRUCTION_NEW:
_walkStats.newFiles++;
break;
case CSYNC_INSTRUCTION_CONFLICT:
_walkStats.conflicts++;
break;
case CSYNC_INSTRUCTION_IGNORE:
_walkStats.ignores++;
break;
case CSYNC_INSTRUCTION_SYNC:
_walkStats.sync++;
break;
case CSYNC_INSTRUCTION_STAT_ERROR:
case CSYNC_INSTRUCTION_ERROR:
/* instructions for the propagator */
case CSYNC_INSTRUCTION_DELETED:
case CSYNC_INSTRUCTION_UPDATED:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_INSTRUCTIONS;
break;
default:
_walkStats.error++;
_walkStats.errorType = WALK_ERROR_WALK;
break;
}
int re = 0;
// qDebug() << _walkStats.seenFiles << ". Path: " << file->path << ": uid= " << file->uid << " - type: " << file->type;
if( !( _walkStats.errorType == WALK_ERROR_NONE || _walkStats.errorType == WALK_ERROR_DIR_PERMS )) {
re = -1;
}
_mutex.unlock();
return re;
}
int CSyncThread::treewalk( TREE_WALK_FILE* file, void *data )
{
int re = static_cast<CSyncThread*>(data)->recordStats( file );
if( re > -1 )
return static_cast<CSyncThread*>(data)->treewalkFile( file );
return -1;
}
int CSyncThread::treewalkFile( TREE_WALK_FILE *file )
{
if( ! file ) return -1;
SyncFileItem item;
item.file = QString::fromUtf8( file->path );
item.instruction = file->instruction;
QFileInfo fi( _source, item.file );
if( !(fi.isWritable() && fi.isExecutable()) ) {
_walkStats.dirPermErrors++;
}
_mutex.lock();
_syncedItems.append(item);
_mutex.unlock();
return 0;
}
CSyncThread::CSyncThread(const QString &source, const QString &target, bool localCheckOnly)
CSyncThread::CSyncThread(const QString &source, const QString &target)
: _source(source)
, _target(target)
, _localCheckOnly( localCheckOnly )
{
_mutex.lock();
@ -196,7 +110,6 @@ void CSyncThread::startSync()
{
qDebug() << "starting to sync " << qApp->thread() << QThread::currentThread();
CSYNC *csync;
QTime walkTime;
emit(started());
@ -210,7 +123,6 @@ void CSyncThread::startSync()
_csyncConfigDir = QString::fromUtf8( csync_get_config_dir( csync ));
_mutex.unlock();
qDebug() << "## CSync Thread local only: " << _localCheckOnly;
csync_set_auth_callback( csync, getauth );
csync_set_log_callback( csync, csyncLogCatcher );
@ -230,11 +142,7 @@ void CSyncThread::startSync()
QTime t;
t.start();
_mutex.lock();
if( _localCheckOnly ) {
csync_set_local_only( csync, true );
}
_mutex.unlock();
csync_set_log_verbosity(csync, 10);
if( csync_init(csync) < 0 ) {
CSYNC_ERROR_CODE err = csync_get_error( csync );
@ -312,48 +220,13 @@ void CSyncThread::startSync()
csync_set_userdata(csync, this);
walkTime.start();
if( csync_walk_local_tree(csync, &treewalk, 0) < 0 ) {
qDebug() << "Error in treewalk.";
if( _walkStats.errorType == WALK_ERROR_WALK ) {
emit csyncError(tr("CSync encountered an error while examining the file system.\n"
"Syncing is not possible."));
} else if( _walkStats.errorType == WALK_ERROR_INSTRUCTIONS ) {
emit csyncError(tr("CSync update generated a strange instruction.\n"
"Please write a bug report."));
}
emit csyncError(tr("Local filesystem problems. Better disable Syncing and check."));
if( csync_reconcile(csync) < 0 ) {
emit csyncError(tr("CSync reconcile failed."));
goto cleanup;
} else {
// only warn, do not stop the sync process.
if( _walkStats.errorType == WALK_ERROR_DIR_PERMS ) {
emit csyncError(tr("The local filesystem has %1 write protected directories."
"That can hinder successful syncing.<p/>"
"Please make sure that all local directories are writeable.").arg(_walkStats.dirPermErrors));
}
}
// emit the treewalk results.
emit treeWalkResult(_syncedItems, _walkStats);
_mutex.lock();
if( _localCheckOnly ) {
_mutex.unlock();
qDebug() << " ..... Local only walk finished: " << walkTime.elapsed();
// we have to go out here as its local check only.
if( csync_propagate(csync) < 0 ) {
emit csyncError(tr("File exchange with ownCloud failed. Sync was stopped."));
goto cleanup;
} else {
_mutex.unlock();
// check if we can write all over.
if( csync_reconcile(csync) < 0 ) {
emit csyncError(tr("CSync reconcile failed."));
goto cleanup;
}
if( csync_propagate(csync) < 0 ) {
emit csyncError(tr("File exchange with ownCloud failed. Sync was stopped."));
goto cleanup;
}
}
cleanup:
csync_destroy(csync);

View file

@ -69,7 +69,7 @@ class CSyncThread : public QObject
{
Q_OBJECT
public:
CSyncThread(const QString &source, const QString &target, bool = false);
CSyncThread(const QString &source, const QString &target);
~CSyncThread();
static void setConnectionDetails( const QString&, const QString&, const QNetworkProxy& );
@ -78,7 +78,6 @@ public:
Q_INVOKABLE void startSync();
signals:
void treeWalkResult(const SyncFileItemVector&, const WalkStats&);
void csyncError( const QString& );
void csyncStateDbFile( const QString& );
@ -88,10 +87,7 @@ signals:
void started();
private:
static int treewalk( TREE_WALK_FILE* file, void *data );
int recordStats( TREE_WALK_FILE* file);
void emitStateDb( CSYNC *csync );
int treewalkFile( TREE_WALK_FILE* );
static int getauth(const char *prompt,
char *buf,
@ -110,10 +106,6 @@ private:
QString _source;
QString _target;
bool _localCheckOnly;
QVector <SyncFileItem> _syncedItems;
WalkStats _walkStats;
};
}

View file

@ -48,7 +48,6 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
QObject::connect(_pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerTimeout()));
_pollTimer->start();
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
_watcher = new Mirall::FolderWatcher(path, this);
MirallConfigFile cfg;
@ -57,7 +56,6 @@ Folder::Folder(const QString &alias, const QString &path, const QString& secondP
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 &)),
@ -153,9 +151,7 @@ bool Folder::syncEnabled() const
void Folder::setSyncEnabled( bool doit )
{
_enabled = doit;
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
_watcher->setEventsEnabled( doit );
#endif
if( doit && ! _pollTimer->isActive() ) {
_pollTimer->start();
}
@ -217,12 +213,10 @@ void Folder::incrementErrorCount()
// of the watcher is doubled.
_errorCount++;
if( _errorCount > 1 ) {
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
int interval = _watcher->eventInterval();
int newInt = 2*interval;
qDebug() << "Set new watcher interval to " << newInt;
_watcher->setEventInterval( newInt );
#endif
_errorCount = 0;
}
}
@ -262,9 +256,7 @@ void Folder::startSync( const QStringList &pathList )
void Folder::slotPollTimerTimeout()
{
qDebug() << "* Polling" << alias() << "for changes. Ignoring all pending events until now";
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
_watcher->clearPendingEvents();
#endif
evaluateSync(QStringList());
}
@ -283,16 +275,12 @@ void Folder::slotChanged(const QStringList &pathList)
void Folder::slotSyncStarted()
{
// disable events until syncing is done
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
_watcher->setEventsEnabled(false);
#endif
}
void Folder::slotSyncFinished(const SyncResult &result)
{
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
_watcher->setEventsEnabled(true);
#endif
qDebug() << "OO folder slotSyncFinished: result: " << int(result.status()) << " local: " << result.localRunOnly();
emit syncStateChange();

View file

@ -35,9 +35,7 @@ class QFileSystemWatcher;
namespace Mirall {
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
class FolderWatcher;
#endif
class Folder : public QObject
{
@ -184,9 +182,7 @@ signals:
void scheduleToSync( const QString& );
protected:
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
FolderWatcher *_watcher;
#endif
int _errorCount;
SyncResult _syncResult;

View file

@ -16,9 +16,7 @@
*/
#include "config.h"
#ifdef USE_INOTIFY
#include <sys/inotify.h>
#endif
#include "inotify.h"
#include "mirall/folder.h"

View file

@ -42,35 +42,12 @@ ownCloudFolder::ownCloudFolder(const QString &alias,
: Folder(alias, path, secondPath, parent)
, _secondPath(secondPath)
, _thread(0)
, _localCheckOnly( false )
, _localFileChanges( false )
, _csync(0)
, _pollTimerCnt(0)
, _csyncError(false)
, _wipeDb(false)
, _lastSeenFiles(0)
{
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
qDebug() << "****** ownCloud folder using watcher *******";
// The folder interval is set in the folder parent class.
#else
/* If local polling is used, the polltimer of class Folder has to fire more
* often
* Set a local poll time of 2000 milliseconds, which results in a 30 seconds
* remote poll interval, defined in slotPollTimerRemoteCheck
*/
MirallConfigFile cfgFile;
_pollTimer->stop();
connect( _pollTimer, SIGNAL(timeout()), this, SLOT(slotPollTimerRemoteCheck()));
setPollInterval( cfgFile.localPollInterval()- 500 + (int)( 1000.0*qrand()/(RAND_MAX+1.0) ) );
_pollTimerExceed = cfgFile.pollTimerExceedFactor();
_pollTimerCnt = _pollTimerExceed-1; // start the syncing quickly!
_pollTimer->start();
qDebug() << "****** ownCloud folder using local poll *******";
#endif
}
ownCloudFolder::~ownCloudFolder()
@ -78,13 +55,6 @@ ownCloudFolder::~ownCloudFolder()
}
/* Only used if INotify is not available. */
void ownCloudFolder::slotPollTimerRemoteCheck()
{
_pollTimerCnt++;
qDebug() << "**** Poll Timer for Folder " << alias() << " increase: " << _pollTimerCnt;
}
bool ownCloudFolder::isBusy() const
{
return ( _thread && _thread->isRunning() );
@ -139,27 +109,15 @@ void ownCloudFolder::startSync(const QStringList &pathList)
url.setScheme( QLatin1String("ownclouds") );
}
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
// if there is a watcher and no polling, ever sync is remote.
_localCheckOnly = false;
_syncResult.clearErrors();
#else
_localCheckOnly = true;
if( _pollTimerCnt >= _pollTimerExceed || _localFileChanges ) {
_localCheckOnly = false;
_pollTimerCnt = 0;
_localFileChanges = false;
_syncResult.clearErrors();
}
#endif
_syncResult.setLocalRunOnly( _localCheckOnly );
// we now have watchers for everything, so every sync is remote.
_syncResult.setLocalRunOnly( false );
Folder::startSync( pathList );
qDebug() << "*** Start syncing url to ownCloud: " << url.toString() << ", with localOnly: " << _localCheckOnly;
qDebug() << "*** Start syncing url to ownCloud: " << url.toString();
_thread = new QThread(this);
_csync = new CSyncThread( path(), url.toString(), _localCheckOnly );
_csync = new CSyncThread( path(), url.toString() );
_csync->moveToThread(_thread);
QList<QNetworkProxy> proxies = QNetworkProxyFactory::proxyForQuery(QUrl(cfgFile.ownCloudUrl()));
@ -177,8 +135,6 @@ void ownCloudFolder::startSync(const QStringList &pathList)
qRegisterMetaType<SyncFileItemVector>("SyncFileItemVector");
qRegisterMetaType<WalkStats>("WalkStats");
connect( _csync, SIGNAL(treeWalkResult(SyncFileItemVector,WalkStats)),
this, SLOT(slotThreadTreeWalkResult(SyncFileItemVector, WalkStats)), Qt::QueuedConnection);
_thread->start();
QMetaObject::invokeMethod(_csync, "startSync", Qt::QueuedConnection);
@ -190,39 +146,6 @@ void ownCloudFolder::slotCSyncStarted()
emit syncStarted();
}
void ownCloudFolder::slotThreadTreeWalkResult(const SyncFileItemVector& items, const WalkStats& wStats )
{
_items = items;
qDebug() << "Seen files: " << wStats.seenFiles;
/* check if there are happend changes in the file system */
qDebug() << "New files: " << wStats.newFiles;
qDebug() << "Updated files: " << wStats.eval;
qDebug() << "Walked files: " << wStats.seenFiles;
qDebug() << "Eval files: " << wStats.eval;
qDebug() << "Removed files: " << wStats.removed;
qDebug() << "Renamed files: " << wStats.renamed;
if( ! _localCheckOnly ) _lastSeenFiles = 0;
_localFileChanges = false;
#if defined(USE_INOTIFY) || defined (Q_OS_MAC)
if( _lastSeenFiles > 0 && _lastSeenFiles != wStats.seenFiles ) {
qDebug() << "*** last seen files different from currently seen number " << _lastSeenFiles << "<>" << wStats.seenFiles << " => full Sync needed";
_localFileChanges = true;
}
if( (wStats.newFiles + wStats.eval + wStats.removed + wStats.renamed) > 0 ) {
qDebug() << "*** Local changes, lets do a full sync!" ;
_localFileChanges = true;
}
if( _pollTimerCnt < _pollTimerExceed ) {
qDebug() << " *** No local changes, finalize, pollTimerCounter is "<< _pollTimerCnt ;
}
#endif
_lastSeenFiles = wStats.seenFiles;
}
void ownCloudFolder::slotCSyncError(const QString& err)
{
_errors.append( err );
@ -244,7 +167,6 @@ void ownCloudFolder::slotCSyncFinished()
_syncResult.setStatus(SyncResult::Success);
}
if( ! _localCheckOnly ) _lastSeenFiles = 0;
if( _thread && _thread->isRunning() ) {
_thread->quit();
}
@ -330,6 +252,7 @@ void ownCloudFolder::wipe()
_wipeDb = false;
}
// TOOD: not called anywhere
SyncFileStatus ownCloudFolder::fileStatus( const QString& file )
{
if( file.isEmpty() ) return STATUS_NONE;

View file

@ -69,22 +69,14 @@ private slots:
void slotCSyncStarted();
void slotCSyncError(const QString& );
void slotCSyncFinished();
void slotThreadTreeWalkResult(const SyncFileItemVector &, const WalkStats& );
void slotPollTimerRemoteCheck();
private:
QString _secondPath;
QThread *_thread;
CSyncThread *_csync;
bool _localCheckOnly;
bool _localFileChanges;
int _pollTimerCnt;
int _pollTimerExceed;
QStringList _errors;
bool _csyncError;
bool _wipeDb;
ulong _lastSeenFiles;
QVector<SyncFileItem> _items;
};