Vfs: Switch on/off only when sync isn't running #6936

Avoids some situations that might cause data loss.
This commit is contained in:
Christian Kamm 2019-01-14 15:48:08 +01:00 committed by Kevin Ottens
parent 5728256763
commit b7079289c2
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2
2 changed files with 70 additions and 31 deletions

View file

@ -457,7 +457,8 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
if (Theme::instance()->showVirtualFilesOption()
&& !folder->supportsVirtualFiles()
&& bestAvailableVfsMode() != Vfs::Off) {
&& bestAvailableVfsMode() != Vfs::Off
&& !folder->isVfsOnOffSwitchPending()) {
ac = menu->addAction(tr("Enable virtual file support (experimental)..."));
connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder);
}
@ -648,27 +649,43 @@ void AccountSettings::slotEnableVfsCurrentFolder()
if (!enable || !folder)
return;
qCInfo(lcAccountSettings) << "Enabling vfs support for folder" << folder->path();
// It is unsafe to switch on vfs while a sync is running - wait if necessary.
auto connection = std::make_shared<QMetaObject::Connection>();
auto switchVfsOn = [folder, connection, this]() {
if (*connection)
QObject::disconnect(*connection);
// Wipe selective sync blacklist
bool ok = false;
auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
for (const auto &entry : oldBlacklist) {
folder->journalDb()->avoidReadFromDbOnNextSync(entry);
qCInfo(lcAccountSettings) << "Enabling vfs support for folder" << folder->path();
// Wipe selective sync blacklist
bool ok = false;
auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
for (const auto &entry : oldBlacklist) {
folder->journalDb()->avoidReadFromDbOnNextSync(entry);
}
// Change the folder vfs mode and load the plugin
folder->setSupportsVirtualFiles(true);
folder->setVfsOnOffSwitchPending(false);
// Wipe pin states to be sure
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::OnlineOnly);
FolderMan::instance()->scheduleFolder(folder);
_ui->_folderList->doItemsLayout();
};
if (folder->isSyncRunning()) {
*connection = connect(folder, &Folder::syncFinished, this, switchVfsOn);
folder->setVfsOnOffSwitchPending(true);
folder->slotTerminateSync();
_ui->_folderList->doItemsLayout();
} else {
switchVfsOn();
}
// Change the folder vfs mode and load the plugin
folder->setSupportsVirtualFiles(true);
// Wipe pin states to be sure
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::OnlineOnly);
FolderMan::instance()->scheduleFolder(folder);
// Update the ui: no selective sync, vfs indicator; size changed
_ui->_folderList->doItemsLayout();
});
}
@ -687,7 +704,9 @@ void AccountSettings::slotDisableVfsCurrentFolder()
"are currently marked as 'available online only' will be downloaded."
"\n\n"
"The only advantage of disabling virtual file support is that the selective sync feature "
"will become available again."));
"will become available again."
"\n\n"
"This action will abort any currently running synchronization."));
msgBox->addButton(tr("Disable support"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
connect(msgBox, &QMessageBox::finished, msgBox, [this, msgBox, folder](int result) {
@ -695,20 +714,36 @@ void AccountSettings::slotDisableVfsCurrentFolder()
if (result != QMessageBox::AcceptRole || !folder)
return;
qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path();
// It is unsafe to switch off vfs while a sync is running - wait if necessary.
auto connection = std::make_shared<QMetaObject::Connection>();
auto switchVfsOff = [folder, connection, this]() {
if (*connection)
QObject::disconnect(*connection);
// Also wipes virtual files, schedules remote discovery
folder->setSupportsVirtualFiles(false);
qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path();
// Wipe pin states and selective sync db
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::AlwaysLocal);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
// Also wipes virtual files, schedules remote discovery
folder->setSupportsVirtualFiles(false);
folder->setVfsOnOffSwitchPending(false);
FolderMan::instance()->scheduleFolder(folder);
// Wipe pin states and selective sync db
folder->journalDb()->wipePinStateForPathAndBelow("");
folder->journalDb()->setPinStateForPath("", PinState::AlwaysLocal);
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
// Update the ui: no selective sync, vfs indicator; size changed
_ui->_folderList->doItemsLayout();
FolderMan::instance()->scheduleFolder(folder);
_ui->_folderList->doItemsLayout();
};
if (folder->isSyncRunning()) {
*connection = connect(folder, &Folder::syncFinished, this, switchVfsOff);
folder->setVfsOnOffSwitchPending(true);
folder->slotTerminateSync();
_ui->_folderList->doItemsLayout();
} else {
switchVfsOff();
}
});
msgBox->open();
}

View file

@ -341,6 +341,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(const std::function<void
"When a file is opened its contents will be downloaded automatically. "
"Alternatively files can be downloaded manually by using their context menu."
"\n\n"
"Switching to this mode will abort any currently running synchronization."
"\n\n"
"This is a new, experimental mode. If you decide to use it, please report any "
"issues that come up."));
} else {
@ -352,6 +354,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(const std::function<void
"Instead, a tiny \"%1\" file will be created for each file that exists on the server. "
"The contents can be downloaded by running these files or by using their context menu."
"\n\n"
"Switching to this mode will abort any currently running synchronization."
"\n\n"
"This is a new, experimental mode. If you decide to use it, please report any "
"issues that come up.")
.arg(APPLICATION_DOTVIRTUALFILE_SUFFIX));