Move touched-files tracking to SyncEngine #4927 (#4946)

This commit is contained in:
ckamm 2016-06-09 12:07:18 +02:00
parent 66f041f74c
commit 28c12a3ca0
7 changed files with 57 additions and 50 deletions

View file

@ -542,27 +542,6 @@ void OwncloudPropagator::scheduleNextJob()
}
}
void OwncloudPropagator::addTouchedFile(const QString& fn)
{
QString file = QDir::cleanPath(fn);
QElapsedTimer timer;
timer.start();
QMutexLocker lock(&_touchedFilesMutex);
_touchedFiles.insert(file, timer);
}
qint64 OwncloudPropagator::timeSinceFileTouched(const QString& fn) const
{
QMutexLocker lock(&_touchedFilesMutex);
if (! _touchedFiles.contains(fn)) {
return -1;
}
return _touchedFiles[fn].elapsed();
}
AccountPtr OwncloudPropagator::account() const
{
return _account;

View file

@ -330,18 +330,6 @@ public:
/** returns the size of chunks in bytes */
static quint64 chunkSize();
/** Records that a file was touched by a job.
*
* Thread-safe.
*/
void addTouchedFile(const QString& fn);
/** Get the ms since a file was touched, or -1 if it wasn't.
*
* Thread-safe.
*/
qint64 timeSinceFileTouched(const QString& fn) const;
AccountPtr account() const;
enum DiskSpaceResult
@ -377,18 +365,24 @@ signals:
/** Emitted when propagation has problems with a locked file. */
void seenLockedFile(const QString &fileName);
/** Emitted when propagation touches a file.
*
* Used to track our own file modifications such that notifications
* from the file watcher about these can be ignored.
*/
void touchedFile(const QString &fileName);
private:
AccountPtr _account;
/** Stores the time since a job touched a file. */
QHash<QString, QElapsedTimer> _touchedFiles;
mutable QMutex _touchedFilesMutex;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// access to signals which are protected in Qt4
friend class PropagateDownloadFileQNAM;
friend class PropagateUploadFileQNAM;
friend class PropagateLocalMkdir;
friend class PropagateLocalRename;
friend class PropagateRemoteMove;
#endif
};

View file

@ -592,8 +592,8 @@ void PropagateDownloadFileQNAM::deleteExistingFolder()
QString conflictDir = FileSystem::makeConflictFileName(
existingDir, Utility::qDateTimeFromTime_t(_item->_modtime));
_propagator->addTouchedFile(existingDir);
_propagator->addTouchedFile(conflictDir);
emit _propagator->touchedFile(existingDir);
emit _propagator->touchedFile(conflictDir);
QString renameError;
if (!FileSystem::rename(existingDir, conflictDir, &renameError)) {
done(SyncFileItem::NormalError, renameError);
@ -753,7 +753,7 @@ void PropagateDownloadFileQNAM::downloadFinished()
}
QString error;
_propagator->addTouchedFile(fn);
emit _propagator->touchedFile(fn);
// The fileChanged() check is done above to generate better error messages.
if (!FileSystem::uncheckedRenameReplace(_tmpFile.fileName(), fn, &error)) {
qDebug() << Q_FUNC_INFO << QString("Rename failed: %1 => %2").arg(_tmpFile.fileName()).arg(fn);

View file

@ -80,8 +80,8 @@ void PropagateRemoteMove::start()
QString versionString = _propagator->account()->serverVersion();
if (versionString.contains('.') && versionString.split('.')[0].toInt() < 7) {
QString originalFile(_propagator->getFilePath(QLatin1String("Shared")));
_propagator->addTouchedFile(originalFile);
_propagator->addTouchedFile(targetFile);
emit _propagator->touchedFile(originalFile);
emit _propagator->touchedFile(targetFile);
QString renameError;
if( FileSystem::rename(targetFile, originalFile, &renameError) ) {
done(SyncFileItem::NormalError, tr("This folder must not be renamed. It is renamed back to its original name."));

View file

@ -163,7 +163,7 @@ void PropagateLocalMkdir::start()
done( SyncFileItem::NormalError, tr("Attention, possible case sensitivity clash with %1").arg(newDirStr) );
return;
}
_propagator->addTouchedFile(newDirStr);
emit _propagator->touchedFile(newDirStr);
QDir localDir(_propagator->_localDir);
if (!localDir.mkpath(_item->_file)) {
done( SyncFileItem::NormalError, tr("could not create folder %1").arg(newDirStr) );
@ -217,8 +217,8 @@ void PropagateLocalRename::start()
return;
}
_propagator->addTouchedFile(existingFile);
_propagator->addTouchedFile(targetFile);
emit _propagator->touchedFile(existingFile);
emit _propagator->touchedFile(targetFile);
QString renameError;
if (!FileSystem::rename(existingFile, targetFile, &renameError)) {
done(SyncFileItem::NormalError, renameError);

View file

@ -95,6 +95,10 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
_excludedFiles.reset(new ExcludedFiles(&_csync_ctx->excludes));
_syncFileStatusTracker.reset(new SyncFileStatusTracker(this));
_clearTouchedFilesTimer.setSingleShot(true);
_clearTouchedFilesTimer.setInterval(30*1000);
connect(&_clearTouchedFilesTimer, SIGNAL(timeout()), SLOT(slotClearTouchedFiles()));
_thread.setObjectName("SyncEngine_Thread");
}
@ -681,6 +685,7 @@ void SyncEngine::startSync()
s_anySyncRunning = true;
_syncRunning = true;
_anotherSyncNeeded = false;
_clearTouchedFilesTimer.stop();
_progressInfo->reset();
@ -945,6 +950,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
this, SLOT(slotProgress(const SyncFileItem &,quint64)));
connect(_propagator.data(), SIGNAL(finished()), this, SLOT(slotFinished()), Qt::QueuedConnection);
connect(_propagator.data(), SIGNAL(seenLockedFile(QString)), SIGNAL(seenLockedFile(QString)));
connect(_propagator.data(), SIGNAL(touchedFile(QString)), SLOT(slotAddTouchedFile(QString)));
// apply the network limits to the propagator
setNetworkLimits(_uploadLimit, _downloadLimit);
@ -1041,6 +1047,8 @@ void SyncEngine::finalize(bool success)
// Delete the propagator only after emitting the signal.
_propagator.clear();
_clearTouchedFilesTimer.start();
}
void SyncEngine::slotProgress(const SyncFileItem& item, quint64 current)
@ -1362,14 +1370,28 @@ SyncFileItem* SyncEngine::findSyncItem(const QString &fileName) const
return 0;
}
void SyncEngine::slotAddTouchedFile(const QString& fn)
{
QString file = QDir::cleanPath(fn);
QElapsedTimer timer;
timer.start();
_touchedFiles.insert(file, timer);
}
void SyncEngine::slotClearTouchedFiles()
{
_touchedFiles.clear();
}
qint64 SyncEngine::timeSinceFileTouched(const QString& fn) const
{
// This copy is essential for thread safety.
QSharedPointer<OwncloudPropagator> prop = _propagator;
if (prop) {
return prop->timeSinceFileTouched(fn);
if (! _touchedFiles.contains(fn)) {
return -1;
}
return -1;
return _touchedFiles[fn].elapsed();
}
AccountPtr SyncEngine::account() const

View file

@ -157,6 +157,12 @@ private slots:
void slotDiscoveryJobFinished(int updateResult);
void slotCleanPollsJobAborted(const QString &error);
/** Records that a file was touched by a job. */
void slotAddTouchedFile(const QString& fn);
/** Wipes the _touchedFiles hash */
void slotClearTouchedFiles();
private:
void handleSyncError(CSYNC *ctx, const char *state);
@ -256,6 +262,12 @@ private:
CSyncChecksumHook _checksum_hook;
bool _anotherSyncNeeded;
/** Stores the time since a job touched a file. */
QHash<QString, QElapsedTimer> _touchedFiles;
/** For clearing the _touchedFiles variable after sync finished */
QTimer _clearTouchedFilesTimer;
};
}