Conflicts resolution, CBL 1.4 Android


#1

Hi,

Using CBL 1.4, SyncGate 2.1.2 and CBS 6.0.0.
I have some code similar to this (from the docs):

private static boolean resolveConflict(final Document d, final String revisionId, final List<SavedRevision> conflicts) {
        return mDatabase.runInTransaction(new TransactionalTask() {
            @Override
            public boolean run() {
                boolean result = false;
                try {
                    for (SavedRevision r : conflicts) {

                        // Version A
                        UnsavedRevision rev = r.createRevision();
                        if (r.getId().equals(revisionId))
                            rev.setUserProperties(r.getUserProperties());
                        else rev.setIsDeletion(true);
                        rev.save(true);                        

                        // Version B
                        if (!r.getId().equals(revisionId) && !r.isDeletion()) {
                            UnsavedRevision rev = r.createRevision();
                            rev.setIsDeletion(true);
                            rev.save(true);
                        }
                }
                result = true;
            } catch (CouchbaseLiteException e) {
                e.printStackTrace();
            }
            return result;
        }
    });

There are two versions to remove conflicted revisions A and B. On a lower rate of documents changes everything works ok, but when rate rise to several times a second sometimes I get document with all revisions deleted. Also version B is more robust then A,

I have continuous push and pull replications. I have database change listener which update conflicts upon event notifications. For testing purposes I have 3 clients A, B and C. A is passive and just observe changes, B and C activly change shared documents.This is a part of log wich is kind of strage to me (just for 1 document from Client A device):
=======================================================================
(1)
Document: d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6 update, conflicted
Added revision: Rev: 62-77c516c2d1de1a89407dd94b9b9d3e1f
EXTERNAL CHANGES
DOCUMENT REVISIONS: 49
Rev: 63-aa7d39dbea3ab211d2e519881f052c3e
-Rev: 62-2f274ecc8a113c2aa717cc2f9574462c [marked as deleted]
Rev: 61-e52fad56bfb7a320104c11caf405159f
-Rev: 61-54008c3d760a6cb96d7754e9a9b539e9 [marked as deleted]
-Rev: 60-037eae923ff3c35613e87a005491802b [marked as deleted]
DOCUMENT CONFLICTS: 2
Rev: 63-aa7d39dbea3ab211d2e519881f052c3e
Rev: 61-e52fad56bfb7a320104c11caf405159f
WINNER: 62-77c516c2d1de1a89407dd94b9b9d3e1f
Rev: 62-77c516c2d1de1a89407dd94b9b9d3e1f
Resolve delete: 63-aa7d39dbea3ab211d2e519881f052c3e
Resolve delete: 61-e52fad56bfb7a320104c11caf405159f
=======================================================================
(2)
Document: d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6 update, conflicted
Added revision: Rev: 63-aa7d39dbea3ab211d2e519881f052c3e
EXTERNAL CHANGES
DOCUMENT REVISIONS: 49
-Rev: 62-f28d60a63040ac7e6dde27217b3d05b1 [marked as deleted]
-Rev: 64-68bde8de6e1d82c72fb608e8c05c8857 [marked as deleted]
-Rev: 62-2f274ecc8a113c2aa717cc2f9574462c [marked as deleted]
-Rev: 61-54008c3d760a6cb96d7754e9a9b539e9 [marked as deleted]
-Rev: 60-037eae923ff3c35613e87a005491802b [marked as deleted]
WINNER: 63-aa7d39dbea3ab211d2e519881f052c3e
Rev: 63-aa7d39dbea3ab211d2e519881f052c3e
=======================================================================
(3)
Document: d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6 delete
Delete rev id: 64-68bde8de6e1d82c72fb608e8c05c8857
Delete add rev id: 64-68bde8de6e1d82c72fb608e8c05c8857
Delete win rev id: 61-e52fad56bfb7a320104c11caf405159f
======================================================================
(4)
Document: d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6 delete
Delete rev id: 62-f28d60a63040ac7e6dde27217b3d05b1
Delete add rev id: 62-f28d60a63040ac7e6dde27217b3d05b1
Delete win rev id: 64-68bde8de6e1d82c72fb608e8c05c8857

At (1) added new revision 62-77 but getLeafRevisions() does not contains it. At this point 2 conflicted revisions 63-aa and 61-e5 deleted.
Next at (2) added another revision 63-aa and again getLeafRevisions() does not contains it. There is no conflicts so this revision is a winner.
Next at (3) added(?) revision 64-68 with _deleted=true but current document already has this revision. CBL says than winning revision now 61-e5 which was deleted at (1).
And finally at (4) added(?) revision 62-f2 with _deleted=true but current document already has this revision. CBL says than winning revision now 64-68 which was deleted(?) at (3) And now this document does not exist nor on server nor on clients.

This is stripped from syncgate log:
2019-01-31T07:43:55.636+03:100 [INF] Cache: Received #7110 after 21ms (“d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6” / “62-77c516c2d1de1a89407dd94b9b9d3e1f”)
2019-01-31T07:43:55.794+03:00 [INF] Cache: Received #7113 after 6ms (“d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6” / “63-aa7d39dbea3ab211d2e519881f052c3e”)
2019-01-31T07:43:56.911+03:00 [INF] Cache: Received #7121 after 7ms (“d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6” / “61-e52fad56bfb7a320104c11caf405159f”)
2019-01-31T07:43:56.921+03:00 [INF] Cache: Received #7122 after 6ms (“d3200e72-9150-4bc7-8ad0-f0a7cbe5fba6” / “64-68bde8de6e1d82c72fb608e8c05c8857”)

Questions:

  1. Why I cant see added revision( see (1) and (2) with getLeafRevisions()?
  2. Which verision of removing unnesessary revision is correct A or B?
  3. Is it ok that on deletion CBL suggest winner which is already deleted too?
  4. What am I doing wrong resolving conflicts?

There is no delete operations on clients with delete method or updating document contents with _deleted=true, only reaction on event Database.ChangeEvent and conflict resolution.

Any help, advise or directed link for further reading would be very appreciated.