-
Notifications
You must be signed in to change notification settings - Fork 817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CFAPI: Handle cancelation of hydration requests #3010
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -264,6 +264,19 @@ Vfs::AvailabilityResult VfsCfApi::availability(const QString &folderPath) | |
return AvailabilityError::NoSuchItem; | ||
} | ||
|
||
void VfsCfApi::cancelHydration(const QString &requestId, const QString & /*path*/) | ||
{ | ||
// Find matching hydration job for request id | ||
const auto hydrationJobsIter = std::find_if(d->hydrationJobs.cbegin(), d->hydrationJobs.cend(), [&](const HydrationJob *job) { | ||
return job->requestId() == requestId; | ||
}); | ||
|
||
// If found, cancel it | ||
if (hydrationJobsIter != d->hydrationJobs.cend()) { | ||
(*hydrationJobsIter)->cancel(); | ||
} | ||
} | ||
|
||
void VfsCfApi::requestHydration(const QString &requestId, const QString &path) | ||
{ | ||
qCInfo(lcCfApi) << "Received request to hydrate" << path << requestId; | ||
|
@@ -331,6 +344,7 @@ void VfsCfApi::scheduleHydrationJob(const QString &requestId, const QString &fol | |
job->setRequestId(requestId); | ||
job->setFolderPath(folderPath); | ||
connect(job, &HydrationJob::finished, this, &VfsCfApi::onHydrationJobFinished); | ||
connect(job, &HydrationJob::canceled, this, &VfsCfApi::onHydrationJobCanceled); | ||
d->hydrationJobs << job; | ||
job->start(); | ||
emit hydrationRequestReady(requestId); | ||
|
@@ -347,6 +361,22 @@ void VfsCfApi::onHydrationJobFinished(HydrationJob *job) | |
} | ||
} | ||
|
||
void VfsCfApi::onHydrationJobCanceled(HydrationJob *job) | ||
{ | ||
const auto folderPath = job->localPath(); | ||
const auto folderRelativePath = job->folderPath(); | ||
|
||
// Remove placeholder file because there might be already pumped | ||
// some data into it | ||
QFile::remove(folderPath + folderRelativePath); | ||
|
||
// Create a new placeholder file | ||
SyncJournalFileRecord record; | ||
params().journal->getFileRecord(folderRelativePath, &record); | ||
const auto item = SyncFileItem::fromSyncJournalFileRecord(record); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If that's really required (see other comment above), then at least it should check the db read actually succeeded and the record is valid, otherwise you could have a malformed item here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @er-vin Okay but how should we recover if the item is malformed? Or should we check if the record is valid before the removal of the placeholder and if the record is invalid then just return early from the function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, probably best to do the db operation first. And leave the file in place if that fails. At least that'd avoid unwanted deletion on next sync. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
createPlaceholder(*item); | ||
} | ||
|
||
VfsCfApi::HydratationAndPinStates VfsCfApi::computeRecursiveHydrationAndPinStates(const QString &folderPath, const Optional<PinState> &basePinState) | ||
{ | ||
Q_ASSERT(!folderPath.endsWith('/')); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is surprising. Isn't the data committed on disk by cfapi only when the request completes? I'd be surprised they'd go through all the trouble to prevent the sync engine from writing directly in the file itself to then leave inconsistent data behind...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you cancel a request and then look at the file size you can see that the file size is not zero bytes anymore. But I'm not sure if there is really already data pumped in. I thought it would be cleaner to just remove it and replace it with an empty placeholder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're slightly confused here. It's already non-zero before the request. The placeholders expose the size of the file as reported by the server metadata even if the file isn't hydrated.
Please test again without that removal and db + placeholder mangling. I mean when the client has to do this kind of things sure, but if that's not required then it's better not too, it's always a risk of ending up with inconsistent data if something fails during the course of such actions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@er-vin Actually, I have noticed what @FlexW mentioned. There is this field called "Size on disk" on every file in Windows if you open its properties dialog. It is growing as the hydration is progressing and its size is zero at the beginning. If one cancels the download in the Progress dialog, the "Size on disk" does not drop to zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah nice that there's a different field in the properties dialog. Didn't spot it the last time.
So yeah I guess it needs that kill + recreate placeholder then... shame on that API, just makes no sense to not let us write to the files directly then. :-)