Code swap does not take effect when second user pulls changes #9289
Draft
khanaffan wants to merge 4 commits into
Draft
Code swap does not take effect when second user pulls changes #9289khanaffan wants to merge 4 commits into
khanaffan wants to merge 4 commits into
Conversation
|
Thanks for explaning this to me Affan. From what I understand -
|
…nsert scenario with undo/redo verification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
imodel-native: iTwin/imodel-native#1439
Summary
When a second user pulls changes, code swaps do not take effect. This is caused by the unique index constraint combined with our conflict handler that is configured to skip on conflict. As a result, any swaps are silently lost.
What Is a Code Swap?
A code swap exchanges the
CodeValuebetween two elements. BecauseCodeValueis protected by a unique index, a direct swap is not possible in a single step. Instead, the swap is implemented as:CodeValues into temporary variables (tempA,tempB).CodeValuetonull(to release the unique index slot).CodeValuetotempB(second element's original value).CodeValuetotempA(first element's original value).Cross-transaction variant
When the swap spans two separate transactions, it works correctly:
CodeValue→nullEach transaction satisfies the unique index in isolation, so no conflict occurs.
Same-transaction variant (broken for undo/redo)
When all four steps occur within a single transaction, undo/redo skips the intermediate
nullassignment because the conflict handler sees the unique index violation during replay and issues a SKIP. The swap is silently dropped.This same failure mode also manifests when:
Root Cause
During replay of the swap operations, the conflict handler encounters a unique index violation on the intermediate or final
CodeValueassignment and chooses to SKIP rather than fail or retry. This causes the swap to be silently lost for any user replaying the changeset.Sequence Diagram
sequenceDiagram participant U1 as User 1 (Author) participant Hub as iModelHub participant U2 as User 2 (Puller) Note over U1: Swap CodeValue: Element A ↔ Element B U1->>U1: tempA = A.CodeValue, tempB = B.CodeValue U1->>U1: Txn 1 — Set A.CodeValue = null U1->>U1: Txn 2 — Set A.CodeValue = tempB U1->>U1: Txn 2 — Set B.CodeValue = tempA Note over U1: ✅ Swap succeeds locally<br/>(unique index satisfied per txn) U1->>Hub: Push changesets (possibly squashed) Note over Hub: Squashed changeset may collapse<br/>Txn 1 + Txn 2 into one delta U2->>Hub: Pull changesets Hub->>U2: Apply squashed changeset Note over U2: Replay: Set A.CodeValue = tempB Note over U2: ❌ Unique index violation detected<br/>(A.CodeValue still = tempA) U2-->>U2: Conflict handler: SKIP Note over U2: ❌ Swap is lost —<br/>U2 retains original stale values Note over U1,U2: Same failure occurs within a single txn<br/>during undo/redo replayImpact
Status
This issue has been reported to the SQLite developers and they are actively working on a fix at the SQLite level. In the meantime, a workaround or mitigation may be needed on our side to detect and re-apply lost swaps.
Related
OR SKIP/ unique index violation handling