Skip to content

Commit 37cf786

Browse files
committed
fix(SyncProcess): Don't associate concurrentCreations with multiple candidates
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent 18b5231 commit 37cf786

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

src/lib/strategies/Default.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,12 +892,24 @@ export default class SyncProcess {
892892
}, ACTION_CONCURRENCY)
893893

894894
const findChainCacheForCreations = {}
895+
// Each target-side concurrent creation may be merged with at most ONE source creation. Without
896+
// this, two source creations that both canMergeWith the same target creation (e.g. duplicate
897+
// titles/urls produced by fuzzing or by a previous reset) each call addMapping against the same
898+
// target id; the second add evicts the first ("X will become unmapped"), orphaning a real item
899+
// which is then silently dropped. Claim a target creation synchronously the moment it is matched
900+
// (before any await) so a concurrent task cannot claim it too.
901+
const claimedTargetCreations = new Set()
895902
await Parallel.each(sourceScanResult.CREATE.getActions(), async(action) => {
896903
const concurrentCreation = targetCreations.find(a => (
904+
!claimedTargetCreations.has(a) &&
897905
action.payload.parentId === Mappings.mapParentId(mappingsSnapshot, a.payload, action.payload.location) &&
898-
action.payload.canMergeWith(a.payload)
906+
action.payload.canMergeWith(a.payload) &&
907+
// Don't bind to a target creation that is already mapped to a *different* item — that bind
908+
// would evict the existing mapping and orphan its counterpart.
909+
!Mappings.wouldEvictUnrelatedMapping(mappingsSnapshot, action.payload, a.payload)
899910
))
900911
if (concurrentCreation) {
912+
claimedTargetCreations.add(concurrentCreation)
901913
// created on both the target and sourcely, try to reconcile
902914
const subScanner = new Scanner(
903915
this.mappings,

0 commit comments

Comments
 (0)