Merge pull request #7893 from nextcloud/backport/7876/stable-3.16

[stable-3.16] prevent infinite sync loop: delay retry after many errors
This commit is contained in:
Matthieu Gallien 2025-02-20 10:25:19 +01:00 committed by GitHub
commit bad1cdaba0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 10 deletions

View File

@ -719,21 +719,49 @@ void FolderMan::scheduleFolder(Folder *f)
qCInfo(lcFolderMan) << "Schedule folder " << alias << " to sync!";
auto syncAgainDelay = std::chrono::seconds(0);
if (f->consecutiveFailingSyncs() > 2 && f->consecutiveFailingSyncs() <= 4) {
syncAgainDelay = std::chrono::seconds(10);
} else if (f->consecutiveFailingSyncs() > 4 && f->consecutiveFailingSyncs() <= 6) {
syncAgainDelay = std::chrono::seconds(30);
} else if (f->consecutiveFailingSyncs() > 6) {
syncAgainDelay = std::chrono::seconds(60);
}
if (!_scheduledFolders.contains(f)) {
if (!f->canSync()) {
qCInfo(lcFolderMan) << "Folder is not ready to sync, not scheduled!";
_socketApi->slotUpdateFolderView(f);
return;
}
f->prepareToSync();
emit folderSyncStateChange(f);
_scheduledFolders.enqueue(f);
emit scheduleQueueChanged();
if (syncAgainDelay == std::chrono::seconds(0)) {
f->prepareToSync();
emit folderSyncStateChange(f);
_scheduledFolders.enqueue(f);
emit scheduleQueueChanged();
startScheduledSyncSoon();
} else {
qCWarning(lcFolderMan()) << "going to delay the next sync run due to too many synchronization errors" << syncAgainDelay;
QTimer::singleShot(syncAgainDelay, this, [this, f] () {
f->prepareToSync();
emit folderSyncStateChange(f);
_scheduledFolders.enqueue(f);
emit scheduleQueueChanged();
startScheduledSyncSoon();
});
}
} else {
qCInfo(lcFolderMan) << "Sync for folder " << alias << " already scheduled, do not enqueue!";
if (syncAgainDelay == std::chrono::seconds(0)) {
startScheduledSyncSoon();
} else {
qCWarning(lcFolderMan()) << "going to delay the next sync run due to too many synchronization errors" << syncAgainDelay;
QTimer::singleShot(syncAgainDelay, this, [this] () {
startScheduledSyncSoon();
});
}
}
startScheduledSyncSoon();
}
void FolderMan::scheduleFolderForImmediateSync(Folder *f)

View File

@ -37,7 +37,7 @@ class TestFolderMan: public QObject
{
Q_OBJECT
FolderMan _fm;
std::unique_ptr<FolderMan> _fm;
signals:
void incomingShareDeleted();
@ -53,6 +53,9 @@ private slots:
void testDeleteEncryptedFiles()
{
_fm.reset({});
_fm.reset(new FolderMan{});
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
QCOMPARE(fakeFolder.currentLocalState().children.count(), 4);
@ -154,6 +157,9 @@ private slots:
void testLeaveShare()
{
_fm.reset({});
_fm.reset(new FolderMan{});
QTemporaryDir dir;
ConfigFile::setConfDir(dir.path()); // we don't want to pollute the user's config file
@ -182,7 +188,7 @@ private slots:
secondShare->permissions.setPermission(OCC::RemotePermissions::IsShared);
FolderMan *folderman = FolderMan::instance();
QCOMPARE(folderman, &_fm);
QCOMPARE(folderman, _fm.get());
OCC::AccountState *accountState = OCC::AccountManager::instance()->accounts().first().data();
const auto folder = folderman->addFolder(accountState, folderDefinition(fakeFolder.localPath()));
QVERIFY(folder);
@ -252,6 +258,9 @@ private slots:
void testCheckPathValidityForNewFolder()
{
_fm.reset({});
_fm.reset(new FolderMan{});
#ifdef Q_OS_WIN
Utility::NtfsPermissionLookupRAII ntfs_perm;
#endif
@ -278,7 +287,7 @@ private slots:
AccountStatePtr newAccountState(new AccountState(account));
FolderMan *folderman = FolderMan::instance();
QCOMPARE(folderman, &_fm);
QCOMPARE(folderman, _fm.get());
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud1")));
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2")));
@ -382,6 +391,9 @@ private slots:
void testFindGoodPathForNewSyncFolder()
{
_fm.reset({});
_fm.reset(new FolderMan{});
// SETUP
QTemporaryDir dir;
@ -405,7 +417,7 @@ private slots:
AccountStatePtr newAccountState(new AccountState(account));
FolderMan *folderman = FolderMan::instance();
QCOMPARE(folderman, &_fm);
QCOMPARE(folderman, _fm.get());
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud/")));
QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2/")));