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::slotPollTimerTimeout() { qDebug() << "* Polling" << alias() << "for changes. Ignoring all pending events until now"; _watcher->clearPendingEvents(); QObject::connect(new RequestEtagJob(secondPath(), this), SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString))); }
void Folder::slotPollTimerTimeout() { qDebug() << "* Polling" << alias() << "for changes. (time since next sync:" << (_timeSinceLastSync.elapsed() / 1000) << "s)"; if (quint64(_timeSinceLastSync.elapsed()) > MirallConfigFile().forceSyncInterval()) { qDebug() << "* Force Sync now"; evaluateSync(QStringList()); } else { RequestEtagJob* job = new RequestEtagJob(secondPath(), this); // check if the etag is different QObject::connect(job, SIGNAL(etagRetreived(QString)), this, SLOT(etagRetreived(QString))); QObject::connect(job, SIGNAL(networkError()), this, SLOT(slotNetworkUnavailable())); } }
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(); } }
bool RequestEtagJob::finished() { qCInfo(lcEtagJob) << "Request Etag of" << reply()->request().url() << "FINISHED WITH STATUS" << replyStatusString(); auto httpCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpCode == 207) { // Parse DAV response QXmlStreamReader reader(reply()); reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); QString etag; while (!reader.atEnd()) { QXmlStreamReader::TokenType type = reader.readNext(); if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { QString name = reader.name().toString(); if (name == QLatin1String("getetag")) { etag += reader.readElementText(); } } } emit etagRetreived(etag); emit finishedWithResult(etag); } else { emit finishedWithResult(HttpError{ httpCode, errorString() }); } return true; }
bool RequestEtagJob::finished() { if (reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 207) { // Parse DAV response QXmlStreamReader reader(reply()); reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); QString etag; while (!reader.atEnd()) { QXmlStreamReader::TokenType type = reader.readNext(); if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { QString name = reader.name().toString(); if (name == QLatin1String("getetag")) { etag += reader.readElementText(); } } } emit etagRetreived(etag); } return true; }