mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
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:
parent
ff1706c729
commit
287c073f00
7 changed files with 12 additions and 250 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_INOTIFY
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
#include "inotify.h"
|
||||
#include "mirall/folder.h"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue