Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve conflicts with continuous replication

I'm new to both CouchDB and PouchDB and am using it to create a contact management system that syncs across mobile and desktop devices, and can be used offline. I am seeing that using PouchDB is infinitely easier than having to write a PHP/MySQL backend.

I have been using it successfully, and when I make conflicting changes on offline devices, CouchDB uses an algorithm to arbitrarily pick a winner and then correctly pushes it to all the devices.

What I would like to do is implement a custom algorithm to merge conflicting records. Here is the algorithm I would like to use:

  1. If a record is deleted on one client and merely updated on another, the updated version wins, unless both clients agree on the delete.
  2. The record with the most recent "modified" timestamp becomes the master, and the older record becomes the secondary.
  3. Any fields that exist only in the secondary (or are empty in the master) are moved over to the master.
  4. The master revision is saved and the secondary is deleted.

CouchDB's guide has a good explanation, but I don't have a clue how to implement it with the PouchDB API during a continuous replication. According to the PouchDB API, there is an "onChange" listener in the replicate options, but I don't understand how to use it to intercept conflicts.

If someone could write a brief tutorial including some sample code, myself and I'm sure many other PouchDB users would appreciate it!

like image 518
Colin Skow Avatar asked Aug 25 '13 23:08

Colin Skow


People also ask

How do you resolve conflict in merge replication?

By default, merge replication uses priority-based logic to resolve conflicts. If a conflicting change is made in two Subscriber databases, the change for the Subscriber with the higher subscription priority wins, or if the priority is the same, the first change to reach the Publisher wins.

Which replication style achieves conflict prevention in database replication?

Primary ownership prevents all replication conflicts, because only a single server permits update access to a set of replicated data.

What is conflict resolution database?

Data Replication provides a conflict resolution mechanism to handle conflicts that might occur when you replicate change data to a database on which other change activity occurs.


1 Answers

Writing an article with examples of exactly how to manage conflict resolution is a really good idea, it can be confusing, but with the lack of one

The idea is the exact same as CouchDB, to resolve conflicts you delete the revisions that didnt win (and write a new winner if needed)

#1 is how CouchDB conflict resolution works anyway, so you dont need to worry about that, deleted leafs dont conflict

function onChange(doc) { 
  if (!doc._conflicts) return;
    collectConflicts(doc._conflicts, function(docs) {
      var master = docs.sort(byTime).unshift();
      for (var doc in docs) {
        for (var prop in doc) {
          if (!(prop in master)) { 
            master[prop] = doc[prop];
          } 
        }
      }
      db.put(master, function(err) {
        if (!err) { 
          for (var doc in docs) {
            db.remove(doc);
          }
        }
      });     
    });
  }
}

db.changes({conflicts: true, onChange: onChange});

This will need error handling etc and could be written much nicer, was just a quick napkin drawing of what the code could look like

like image 154
Dale Avatar answered Nov 02 '22 11:11

Dale