mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Core: Fixed potential out-of-sync issue if user cancels while in the middle of delta step
This commit is contained in:
parent
585ccc2b8b
commit
c5214b6c44
@ -607,4 +607,24 @@ describe('Synchronizer', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('items should be downloaded again when user cancels in the middle of delta operation', async (done) => {
|
||||||
|
let folder1 = await Folder.save({ title: "folder1" });
|
||||||
|
let note1 = await Note.save({ title: "un", is_todo: 1, parent_id: folder1.id });
|
||||||
|
await synchronizer().start();
|
||||||
|
|
||||||
|
await switchClient(2);
|
||||||
|
|
||||||
|
synchronizer().debugFlags_ = ['cancelDeltaLoop2'];
|
||||||
|
let context = await synchronizer().start();
|
||||||
|
let notes = await Note.all();
|
||||||
|
expect(notes.length).toBe(0);
|
||||||
|
|
||||||
|
synchronizer().debugFlags_ = [];
|
||||||
|
await synchronizer().start({ context: context });
|
||||||
|
notes = await Note.all();
|
||||||
|
expect(notes.length).toBe(1);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -22,6 +22,10 @@ class Synchronizer {
|
|||||||
this.appType_ = appType;
|
this.appType_ = appType;
|
||||||
this.cancelling_ = false;
|
this.cancelling_ = false;
|
||||||
|
|
||||||
|
// Debug flags are used to test certain hard-to-test conditions
|
||||||
|
// such as cancelling in the middle of a loop.
|
||||||
|
this.debugFlags_ = [];
|
||||||
|
|
||||||
this.onProgress_ = function(s) {};
|
this.onProgress_ = function(s) {};
|
||||||
this.progressReport_ = {};
|
this.progressReport_ = {};
|
||||||
|
|
||||||
@ -354,10 +358,11 @@ class Synchronizer {
|
|||||||
let context = null;
|
let context = null;
|
||||||
let newDeltaContext = null;
|
let newDeltaContext = null;
|
||||||
let localFoldersToDelete = [];
|
let localFoldersToDelete = [];
|
||||||
|
let hasCancelled = false;
|
||||||
if (lastContext.delta) context = lastContext.delta;
|
if (lastContext.delta) context = lastContext.delta;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (this.cancelling()) break;
|
if (this.cancelling() || hasCancelled) break;
|
||||||
|
|
||||||
let listResult = await this.api().delta('', {
|
let listResult = await this.api().delta('', {
|
||||||
context: context,
|
context: context,
|
||||||
@ -372,7 +377,10 @@ class Synchronizer {
|
|||||||
|
|
||||||
let remotes = listResult.items;
|
let remotes = listResult.items;
|
||||||
for (let i = 0; i < remotes.length; i++) {
|
for (let i = 0; i < remotes.length; i++) {
|
||||||
if (this.cancelling()) break;
|
if (this.cancelling() || this.debugFlags_.indexOf('cancelDeltaLoop2') >= 0) {
|
||||||
|
hasCancelled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let remote = remotes[i];
|
let remote = remotes[i];
|
||||||
if (!BaseItem.isSystemPath(remote.path)) continue; // The delta API might return things like the .sync, .resource or the root folder
|
if (!BaseItem.isSystemPath(remote.path)) continue; // The delta API might return things like the .sync, .resource or the root folder
|
||||||
@ -443,12 +451,19 @@ class Synchronizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If user has cancelled, don't record the new context (2) so that synchronisation
|
||||||
|
// can start again from the previous context (1) next time. It is ok if some items
|
||||||
|
// have been synced between (1) and (2) because the loop above will handle the same
|
||||||
|
// items being synced twice as an update. If the local and remote items are indentical
|
||||||
|
// the update will simply be skipped.
|
||||||
|
if (!hasCancelled) {
|
||||||
if (!listResult.hasMore) {
|
if (!listResult.hasMore) {
|
||||||
newDeltaContext = listResult.context;
|
newDeltaContext = listResult.context;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
context = listResult.context;
|
context = listResult.context;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
outputContext.delta = newDeltaContext ? newDeltaContext : lastContext.delta;
|
outputContext.delta = newDeltaContext ? newDeltaContext : lastContext.delta;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user