I understand that Couchbase uses a “most revisions wins” strategy for resolving sync conflicts. Has there been any discussion about adopting a more advanced Operational Transform approach, instead?
Example
Consider this case, where two users, Alice and Bob, start with identical state on a document:
"someDoc": {
"title": "Blah",
"children": ["A", "B", "C"]
}
Alice adds a new child (D) while her device is briefly disconnected from the Internet:
"someDoc": {
"title": "Blah",
"children": ["A", "B", "C", "D"]
}
Meanwhile, Bob, who remains connected, makes two back-to-back changes on his end, deleting A and then deleting B (he does not yet have Alice’s change, adding D), so he ends up in this state, which syncs to the cloud:
"someDoc": {
"title": "Blah",
"children": ["C"]
}
If I understand the docs correctly, when Alice reconnects and sync completes, Bob’s document “wins” because it has more revisions. So the final state that both Alice and Bob get is:
"someDoc": {
"title": "Blah",
"children": ["C"]
}
But this is pretty naive conflict-resolution. What we really want is, “Integrate the changes that each user has made,” (an operational transform) so that we end up with this final state:
"someDoc": {
"title": "Blah",
"children": ["C", "D"]
}
In my app’s case, the entries in the children
array are UUIDs to other documents in the object graph. So losing one to the ether causes corruption in the graph. (I’m currently minimizing the chances of this by disabling edits when sync is offline, but that’s…not great.)
I understand that Couchbase lets me write custom conflict resolvers. But to apply operational transforms correctly is a big job that requires a lot of tracking—it’s the exact sort of thing that a paid sync service should really provide, no?
Realm Sync has (had) it. Is there any roadmap for achieving this in Couchbase Sync Gateway?