void Folder::slotWatchedPathChanged(const QString& path) { // When no sync is running or it's in the prepare phase, we can // always schedule a new sync. if (! _engine || _syncResult.status() == SyncResult::SyncPrepare) { emit scheduleToSync(this); return; } // The folder watcher fires a lot of bogus notifications during // a sync operation, both for actual user files and the database // and log. Therefore we check notifications against operations // the sync is doing to filter out our own changes. bool ownChange = false; #ifdef Q_OS_MAC Q_UNUSED(path) // On OSX the folder watcher does not report changes done by our // own process. Therefore nothing needs to be done here! #else // Use the path to figure out whether it was our own change const auto maxNotificationDelay = 15*1000; qint64 time = _engine->timeSinceFileTouched(path); if (time != -1 && time < maxNotificationDelay) { ownChange = true; } #endif if (! ownChange) { emit scheduleToSync(this); } }
void Folder::slotRunEtagJob() { qDebug() << "* Trying to check" << alias() << "for changes via ETag check. (time since last sync:" << (_timeSinceLastSyncDone.elapsed() / 1000) << "s)"; Q_ASSERT(_accountState ); AccountPtr account = _accountState->account(); if (!_requestEtagJob.isNull()) { qDebug() << Q_FUNC_INFO << alias() << "has ETag job queued, not trying to sync"; return; } if (_definition.paused || !_accountState->isConnected()) { qDebug() << "Not syncing. :" << alias() << _definition.paused << AccountState::stateString(_accountState->state()); return; } bool forceSyncIntervalExpired = quint64(_timeSinceLastSyncDone.elapsed()) > ConfigFile().forceSyncInterval(); bool syncAgainAfterFail = _consecutiveFailingSyncs > 0 && _consecutiveFailingSyncs < 3; // There are several conditions under which we trigger a full-discovery sync: // * When a suitably long time has passed since the last sync finished // * When the last sync failed (only a couple of times) // * When the last sync requested another sync to be done (only a couple of times) // // Note that the etag check (see below) and the file watcher may also trigger // syncs. if (forceSyncIntervalExpired || _forceSyncOnPollTimeout || syncAgainAfterFail) { if (forceSyncIntervalExpired) { qDebug() << "** Force Sync, because it has been " << _timeSinceLastSyncDone.elapsed() << "ms " << "since the last sync"; } if (_forceSyncOnPollTimeout) { qDebug() << "** Force Sync, because it was requested"; } if (syncAgainAfterFail) { qDebug() << "** Force Sync, because the last" << _consecutiveFailingSyncs << "syncs failed, last status:" << _syncResult.statusString(); } _forceSyncOnPollTimeout = false; emit scheduleToSync(this); } else { // Do the ordinary etag check for the root folder and only schedule a real // sync if it's different. _requestEtagJob = new RequestEtagJob(account, remotePath(), this); // check if the etag is different QObject::connect(_requestEtagJob, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString))); FolderMan::instance()->slotScheduleETagJob(alias(), _requestEtagJob); // The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null. } }
void Folder::evaluateSync(const QStringList &/*pathList*/) { if( !_enabled ) { qDebug() << "*" << alias() << "sync skipped, disabled!"; return; } _syncResult.setStatus( SyncResult::NotYetStarted ); emit scheduleToSync( alias() ); }
void Folder::etagRetreived(const QString& etag) { qDebug() << "* Compare etag with previous etag: " << (_lastEtag != etag); // re-enable sync if it was disabled because network was down FolderMan::instance()->setSyncEnabled(true); if (_lastEtag != etag) { _lastEtag = etag; emit scheduleToSync(alias()); } }
void Folder::etagRetreived(const QString& etag) { qDebug() << "* Compare etag with previous etag: last:" << _lastEtag << ", received:" << etag; // re-enable sync if it was disabled because network was down FolderMan::instance()->setSyncEnabled(true); if (_lastEtag != etag) { _lastEtag = etag; emit scheduleToSync(this); } if( _accountState ) { _accountState->tagLastSuccessfullETagRequest(); } }
void Folder::slotPollTimerTimeout() { qDebug() << "* Polling" << alias() << "for changes. (time since last sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)"; if (quint64(_timeSinceLastSync.elapsed()) > MirallConfigFile().forceSyncInterval() || !(_syncResult.status() == SyncResult::Success ||_syncResult.status() == SyncResult::Problem)) { qDebug() << "** Force Sync now, state is " << _syncResult.statusString(); emit scheduleToSync(alias()); } else { RequestEtagJob* job = new RequestEtagJob(AccountManager::instance()->account(), remotePath(), this); // check if the etag is different QObject::connect(job, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString))); QObject::connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotNetworkUnavailable())); job->start(); } }
void Folder::evaluateSync(const QStringList &pathList) { if( !_enabled ) { qDebug() << "*" << alias() << "sync skipped, disabled!"; return; } if (!_online && onlyOnlineEnabled()) { qDebug() << "*" << alias() << "sync skipped, not online"; return; } // stop the poll timer here. Its started again in the slot of // sync finished. qDebug() << "* " << alias() << "Poll timer disabled"; _pollTimer->stop(); _syncResult.setStatus( SyncResult::NotYetStarted ); emit scheduleToSync( alias() ); }