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:
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!
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.
Primary ownership prevents all replication conflicts, because only a single server permits update access to a set of replicated data.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With