Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

couchdb - 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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...