Skip to content

Commit 1be0c22

Browse files
committed
fix(SyncProcess): reconcileReorderings based on both donePlans
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent 2253d42 commit 1be0c22

4 files changed

Lines changed: 34 additions & 19 deletions

File tree

src/lib/strategies/Default.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -290,15 +290,21 @@ export default class SyncProcess {
290290
Logger.log('Executing local plan')
291291
await this.execute(this.localTree, this.localPlanStage2, ItemLocation.LOCAL, this.localDonePlan, this.localReorders)
292292

293+
// Remove mappings only after both plans have been executed
294+
this.localDonePlan.REMOVE.getActions().forEach(action => this.removeMapping(this.localTree, action.payload))
295+
this.serverDonePlan.REMOVE.getActions().forEach(action => this.removeMapping(this.localTree, action.payload))
296+
293297
if (this.canceled) {
294298
throw new CancelledSyncError()
295299
}
296300

297301
if ('orderFolder' in this.server && !this.localReordersFinal) {
298302
// mappings have been updated, reload
299303
mappingsSnapshot = this.mappings.getSnapshot()
300-
this.localReordersFinal = this.reconcileReorderings(this.localReorders, this.localDonePlan, ItemLocation.LOCAL, mappingsSnapshot)
301-
this.serverReorderFinal = this.reconcileReorderings(this.serverReorders, this.serverDonePlan, ItemLocation.SERVER, mappingsSnapshot)
304+
const localReorders = this.reconcileReorderings(this.localReorders, this.localDonePlan, ItemLocation.LOCAL, mappingsSnapshot)
305+
const serverReorders = this.reconcileReorderings(this.serverReorders, this.serverDonePlan, ItemLocation.SERVER, mappingsSnapshot)
306+
this.localReordersFinal = this.reconcileReorderings(localReorders, this.serverDonePlan, ItemLocation.LOCAL, mappingsSnapshot).map(mappingsSnapshot, ItemLocation.LOCAL)
307+
this.serverReorderFinal = this.reconcileReorderings(serverReorders, this.localDonePlan, ItemLocation.SERVER, mappingsSnapshot).map(mappingsSnapshot, ItemLocation.SERVER)
302308
}
303309

304310
if (this.canceled) {
@@ -623,7 +629,7 @@ export default class SyncProcess {
623629
const concurrentMove = targetMoves.find(a =>
624630
action.payload.type === a.payload.type && Mappings.mappable(mappingsSnapshot, action.payload, a.payload))
625631
if (concurrentMove) {
626-
// Moved both on target and sourcely, source has precedence: do nothing sourcely
632+
// Moved both on target and sourcely, master has precedence: do nothing on master
627633
return
628634
}
629635
}
@@ -1065,7 +1071,6 @@ export default class SyncProcess {
10651071
}
10661072

10671073
await action.payload.visitRemove(resource)
1068-
await this.removeMapping(resource, action.payload)
10691074
diff.retract(action)
10701075
donePlan.REMOVE.commit(action)
10711076
this.updateProgress()
@@ -1098,15 +1103,15 @@ export default class SyncProcess {
10981103

10991104
reconcileReorderings<L1 extends TItemLocation, L2 extends TItemLocation>(
11001105
targetReorders: Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>>,
1101-
targetDonePlan: PlanStage3<L2, TItemLocation, L1>,
1106+
targetOrSourceDonePlan: PlanStage3<TItemLocation, TItemLocation, TItemLocation>,
11021107
targetLocation: L1,
11031108
mappingSnapshot: MappingSnapshot
1104-
) : Diff<L1, TItemLocation, ReorderAction<L1, TItemLocation>> {
1109+
) : Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>> {
11051110
Logger.log('Reconciling reorders to create a plan')
11061111

1107-
const targetCreations = targetDonePlan.CREATE.getActions()
1108-
const targetRemovals = targetDonePlan.REMOVE.getActions()
1109-
const targetMoves = targetDonePlan.MOVE.getActions()
1112+
const targetCreations = targetOrSourceDonePlan.CREATE.getActions()
1113+
const targetRemovals = targetOrSourceDonePlan.REMOVE.getActions()
1114+
const targetMoves = targetOrSourceDonePlan.MOVE.getActions()
11101115
const targetCreationsAndMoves : Action<TItemLocation, TItemLocation>[] = (targetCreations as Action<TItemLocation, TItemLocation>[]).concat(targetMoves)
11111116
const targetTree = targetLocation === ItemLocation.LOCAL ? this.localTreeRoot : this.serverTreeRoot
11121117

@@ -1122,7 +1127,8 @@ export default class SyncProcess {
11221127

11231128
const removed = targetRemovals
11241129
.filter(removal =>
1125-
Diff.findChain(mappingSnapshot, targetCreationsAndMoves, targetTree, oldReorderAction.payload, removal))
1130+
removal.payload.findItem(reorderAction.payload.type, reorderAction.payload.id) ||
1131+
Diff.findChain(mappingSnapshot, targetCreationsAndMoves, targetTree, reorderAction.payload, removal))
11261132
if (removed.length) {
11271133
return
11281134
}
@@ -1186,7 +1192,7 @@ export default class SyncProcess {
11861192
newReorders.commit(reorderAction)
11871193
})
11881194

1189-
return newReorders.map(mappingSnapshot, targetLocation)
1195+
return newReorders
11901196
}
11911197

11921198
async executeReorderings(resource:OrderFolderResource<TItemLocation>, reorderings:Diff<TItemLocation, TItemLocation, ReorderAction<TItemLocation, TItemLocation>>):Promise<void> {

src/lib/strategies/Merge.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ export default class MergeSyncProcess extends DefaultSyncProcess {
175175

176176
reconcileReorderings<L1 extends TItemLocation, L2 extends TItemLocation>(
177177
targetReorders: Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>>,
178-
targetDonePlan: PlanStage3<L2, TItemLocation, L1>,
178+
targetOrSourceDonePlan: PlanStage3<TItemLocation, TItemLocation, TItemLocation>,
179179
targetLocation: L1,
180180
mappingSnapshot: MappingSnapshot
181-
) : Diff<L1, TItemLocation, ReorderAction<L1, TItemLocation>> {
182-
return super.reconcileReorderings(targetReorders, targetDonePlan, targetLocation, mappingSnapshot)
181+
) : Diff<L2, TItemLocation, ReorderAction<L2, TItemLocation>> {
182+
return super.reconcileReorderings(targetReorders, targetOrSourceDonePlan, targetLocation, mappingSnapshot)
183183
}
184184

185185
async loadChildren(serverTreeRoot: Folder<typeof ItemLocation.SERVER>):Promise<void> {

src/lib/strategies/Unidirectional.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ export default class UnidirectionalSyncProcess extends DefaultStrategy {
181181

182182
await this.executeRevert(target, this.revertPlan, this.direction, this.revertDonePlan, sourceScanResult.REORDER)
183183

184+
if (this.direction === ItemLocation.LOCAL) {
185+
this.revertDonePlan.REMOVE.getActions().forEach(action => this.removeMapping(this.localTree, action.payload))
186+
} else {
187+
this.revertDonePlan.REMOVE.getActions().forEach(action => this.removeMapping(this.server, action.payload))
188+
}
189+
184190
if ('orderFolder' in this.server && !this.revertReorders) {
185191
const mappingsSnapshot = this.mappings.getSnapshot()
186192
Logger.log('Mapping reorderings')

src/test/test.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5321,15 +5321,18 @@ describe('Floccus', function() {
53215321
const tree2AfterThirdSync = await account2.localTree.getBookmarksTree(
53225322
true
53235323
)
5324+
console.log('Checking local tree of acc2')
53245325
expectTreeEqual(
53255326
tree2AfterThirdSync,
53265327
tree2BeforeThirdSync,
53275328
false
53285329
)
5329-
serverTreeAfterThirdSync.title = tree2AfterThirdSync.title
5330+
console.log('All good')
5331+
console.log('Checking server tree')
5332+
serverTreeAfterThirdSync.title = tree2BeforeThirdSync.title
53305333
expectTreeEqual(
53315334
serverTreeAfterThirdSync,
5332-
tree2AfterThirdSync,
5335+
tree2BeforeThirdSync,
53335336
false
53345337
)
53355338
console.log('Second round second half ok')
@@ -7174,8 +7177,8 @@ describe('Floccus', function() {
71747177
.filter(item => item.id !== tree2AfterFirstSync.id)
71757178
}
71767179

7177-
await randomlyManipulateTree(account1, folders1, bookmarks1, 20)
7178-
await randomlyManipulateTree(account2, folders2, bookmarks2, 20)
7180+
await randomlyManipulateTree(account1, folders1, bookmarks1, RANDOM_MANIPULATION_ITERATIONS)
7181+
await randomlyManipulateTree(account2, folders2, bookmarks2, RANDOM_MANIPULATION_ITERATIONS)
71797182

71807183
console.log(' acc1: Moved items')
71817184

@@ -7300,7 +7303,7 @@ describe('Floccus', function() {
73007303
}
73017304
})
73027305

7303-
it('should handle fuzzed changes with deletions from two clients', async function() {
7306+
it('should handle fuzzed changes with deletions from two clients (normal)', async function() {
73047307
const localRoot = account1.getData().localRoot
73057308
let bookmarks1 = []
73067309
let folders1 = []

0 commit comments

Comments
 (0)