How to solve conflicts at replication time?


#1

Hello,
i’m using android couchbase lite. I have an android client which is in pull replication with a sync_gateway.

It may happen that during pull, conflicts are created on documents. I would like to solve conflicts during the replication time, so i thought i could do something like this:

pull.addChangeListener(new Replication.ChangeListener() {
            @Override
            public void changed(Replication.ChangeEvent event) {
                // will be called back when the pull replication status changes

                if (event.getSource().getStatus() != Replication.ReplicationStatus.REPLICATION_OFFLINE) {

                    List<String> docIds = event.getSource().getDocIds();
                    if (docIds != null) {

                        for (String docId : docIds) {

                            Document doc = database.getDocument(docId);
                           
                            List<SavedRevision> conflicts = null;
                            try {
                                conflicts = doc.getConflictingRevisions();
                            } catch (CouchbaseLiteException e) {
                                e.printStackTrace();
                                L.e("Errore mentre recupero le versioni in conflitto", e);
                            }
                            //here i would solve the conflicts but i never reach this point as docIds is always null
                        }
                    }
                }
            }
        });

The problem is that event.getSource().getDocIds() is always null.
Is there a way to intercept all the documents that are pulled and then solve the conflicts at that moment?

Here it is suggested to solve conflict at document read-time but i would like to avoid that and solve it immediately when the conflict is generated (that is at pull time).

I also know i could add a document listener as explained here but i may have up to 80000 documents so i don’t know if it is good from a performance view but more important, documents will be created on server side and transferred to mobile via pull replication so i don’t know how to add the listener if i don’t know that the document has been created.


#2

Use a database change listener. The change.source will be non-null for a doc added by a replication.


#3

Ok. Is it better to use the change listener to find the modified documents and verify if they have a conflict or is it better to invoke a find-all-conflicts query with Query.AllDocsMode.ONLY_CONFLICTS option when the replication is ended (IDLE status) and solve the conflicts then?

I have maybe 80000 documents on my android cblite so i don’t know if all docs query will be fast


#4

The DatabaseChange object will tell you if the document is in conflict. Observing database change notifications and looking for that flag is the cheapest way to detect conflicts; there’s almost zero overhead.

The OnlyConflicts query should be pretty fast; probably somewhat faster with ForestDB, but I haven’t benchmarked it. It will slow down with bigger databases, though.