-
Notifications
You must be signed in to change notification settings - Fork 140
CBG-4905: update defualt resolver for blip tester #7907
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
base: main
Are you sure you want to change the base?
Changes from all commits
3873707
4a68027
74a6712
ce08c33
b50b1cb
f209987
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 |
|---|---|---|
|
|
@@ -339,25 +339,36 @@ func (cd *clientDoc) _hasConflict(t testing.TB, incomingHLV *db.HybridLogicalVec | |
| return false | ||
| } | ||
|
|
||
| func (btcc *BlipTesterCollectionClient) _resolveConflict(incomingHLV *db.HybridLogicalVector, incomingBody []byte, localDoc *clientDocRev) (body []byte, hlv db.HybridLogicalVector) { | ||
| func (btcc *BlipTesterCollectionClient) _resolveConflict(incomingHLV *db.HybridLogicalVector, incomingBody []byte, incomingIsDelete bool, localDoc *clientDocRev) (body []byte, hlv db.HybridLogicalVector, isTombstone bool) { | ||
| switch btcc.parent.ConflictResolver { | ||
| case ConflictResolverLastWriteWins: | ||
| return btcc._resolveConflictLWW(incomingHLV, incomingBody, localDoc) | ||
| return btcc._resolveConflictLWW(incomingHLV, incomingBody, incomingIsDelete, localDoc) | ||
| } | ||
| btcc.TB().Fatalf("Unknown conflict resolver %q - cannot resolve detected conflict", btcc.parent.ConflictResolver) | ||
| return nil, db.HybridLogicalVector{} | ||
| return nil, db.HybridLogicalVector{}, isTombstone | ||
| } | ||
|
|
||
| func (btcc *BlipTesterCollectionClient) _resolveConflictLWW(incomingHLV *db.HybridLogicalVector, incomingBody []byte, latestLocalRev *clientDocRev) (body []byte, hlv db.HybridLogicalVector) { | ||
| func (btcc *BlipTesterCollectionClient) _resolveConflictLWW(incomingHLV *db.HybridLogicalVector, incomingBody []byte, incomingIsDelete bool, latestLocalRev *clientDocRev) (body []byte, hlv db.HybridLogicalVector, isTombstone bool) { | ||
| latestLocalHLV := latestLocalRev.HLV | ||
| updatedHLV := latestLocalRev.HLV.Copy() | ||
| localDeleted := latestLocalRev.isDelete | ||
| if localDeleted && !incomingIsDelete { | ||
| // resolve in favour of local document | ||
| incomingHLV.UpdateWithIncomingHLV(updatedHLV) | ||
| return latestLocalRev.body, *updatedHLV, true | ||
| } | ||
| if incomingIsDelete && !localDeleted { | ||
| // resolve in favour of remote document | ||
| updatedHLV.UpdateWithIncomingHLV(incomingHLV) | ||
| return incomingBody, *updatedHLV, true | ||
| } | ||
| // resolve conflict in favor of remote document | ||
| if incomingHLV.Version > latestLocalHLV.Version { | ||
| updatedHLV.UpdateWithIncomingHLV(incomingHLV) | ||
| return incomingBody, *updatedHLV | ||
| return incomingBody, *updatedHLV, incomingIsDelete | ||
| } | ||
| incomingHLV.UpdateWithIncomingHLV(updatedHLV) | ||
| return latestLocalRev.body, *updatedHLV | ||
| return latestLocalRev.body, *updatedHLV, latestLocalRev.isDelete | ||
| } | ||
|
|
||
| type BlipTesterCollectionClient struct { | ||
|
|
@@ -2180,14 +2191,18 @@ func (btcc *BlipTesterCollectionClient) addRev(ctx context.Context, docID string | |
| btcc.seqLock.Lock() | ||
| defer btcc.seqLock.Unlock() | ||
| newClientSeq := btcc._nextSequence() | ||
| isTombstone := false | ||
|
|
||
| newBody := opts.body | ||
| newVersion := opts.incomingVersion | ||
| doc, hasLocalDoc := btcc._getClientDoc(docID) | ||
| updatedHLV := doc._getLatestHLVCopy(btcc.TB()) | ||
| require.NotNil(btcc.TB(), updatedHLV, "updatedHLV should not be nil for docID %q", docID) | ||
| if doc._hasConflict(btcc.TB(), opts.incomingHLV) { | ||
| newBody, updatedHLV = btcc._resolveConflict(opts.incomingHLV, opts.body, doc._latestRev(btcc.TB())) | ||
| newBody, updatedHLV, isTombstone = btcc._resolveConflict(opts.incomingHLV, opts.body, opts.isDelete, doc._latestRev(btcc.TB())) | ||
|
Collaborator
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. same question as above, can we rely on newBody == nil to determine if this is a tombstone? |
||
| if isTombstone { | ||
| opts.isDelete = true | ||
| } | ||
| base.DebugfCtx(ctx, base.KeySGTest, "Resolved conflict for docID %q, incomingHLV:%#v, existingHLV:%#v, updatedHLV:%#v", docID, opts.incomingHLV, doc._latestRev(btcc.TB()).HLV, updatedHLV) | ||
| } else { | ||
| base.DebugfCtx(ctx, base.KeySGTest, "No conflict") | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -127,6 +127,34 @@ func (p Peers) SortedPeers() iter.Seq2[string, Peer] { | |||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // peerIsServerSide returns true if the peer is a Couchbase Server or Sync Gateway peer. | ||||||||||
| func peerIsServerSide(p Peer) bool { | ||||||||||
| return p.Type() == PeerTypeCouchbaseServer || p.Type() == PeerTypeSyncGateway | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // conflictNotExpectedOnCBL will return true if no conflict is expected for delete and resurrect operations for | ||||||||||
| // topologies with cbl peer in them and false for expected conflict | ||||||||||
| func conflictNotExpectedOnCBL(deletePeer Peer, resurrectPeer Peer, delPeerName string, resPeerName string) bool { | ||||||||||
| if delPeerName == "cbl1" { | ||||||||||
|
Collaborator
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. Can we use something to determine winner or loser based on logic like Also, putting the logic based on how the replication works I think is required rather than relying on numbers, especially when implementing Full Active-Active Bidirectional XDCR with CBL Crossover topology in the future. |
||||||||||
| // cbl delete will mean cbs resurrect has a conflict | ||||||||||
|
Comment on lines
+138
to
+139
|
||||||||||
| if delPeerName == "cbl1" { | |
| // cbl delete will mean cbs resurrect has a conflict | |
| // If the delete peer is a Couchbase Lite peer, conflict is expected. | |
| if strings.HasPrefix(delPeerName, "cbl") { |
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.
Do we just know that incomingIsDelete
? if incomingBody == nil