In My App with CB Lite DB020(Android), ConflictResolver is called endless loop during three device or much more!

Three or much more devices are running my app, i set ConflictResolver with ::
ConflictResolver getConflictResolver(){
/**
* Example: Conflict resolver that merges Mine and Their document.
*/
return new ConflictResolver() {
@Override
public ReadOnlyDocument resolve(Conflict conflict) {
ReadOnlyDocument mine = conflict.getMine();
ReadOnlyDocument theirs = conflict.getTheirs();

    Document resolved = new Document();
    Set<String> changed = new HashSet<>();

    // copy all data from theirs document
    for (String key : theirs)
    {
      resolved.setObject(key, theirs.getObject(key));
      changed.add(key);
    }

    // copy all data from mine which are not in mine document
    for (String key : mine)
    {
      if (!changed.contains(key))
        resolved.setObject(key, mine.getObject(key));
    }

    return resolved;
  }
};

but when Documents conflict, this ConflictResolver function is called endless loop during
these devices. this bug happens in the todo Demo also!

@hideki do you know what could be causing this issue?

I don’t know the root cause of this. We need to reproduce this.
Filed the ticket: https://github.com/couchbase/couchbase-lite-android/issues/1470

you run the todo app on three android devices and update the same Document on the two devices at the same time ,this problem will be happened!

hi,hideki. do you have a temporal method avoid this bug. Because my app is running on my customers . i must resolve it now, thank you very much! Just ask, are you Chinese?:)

Well, Not sure how to avoid it without knowing what’s causing it . Looks like this issue is being tracked for DB22. If a fix is in sooner, then you can pull and build from source yourself without having to wait for DB 22.

One suggestion - An an interim, to avoid crashes, you could consider going with the default system provided resolver or a simple resolver that picks either “mine” or “theirs” instead of merging the two . The resulting document state may not be what your app logic expects but IMO, that would be a better experience than an app crash. The user can re-apply their updates.

BTW, just some thoughts about your resolver - Of course its entirely unto your app semantics on how you choose to resolve conflict so my comments are more out of curiosity - Your resolved document seems to be a mash-up of existing properties from “theirs” and new properties from “mine”. In other words, it seems like existing properties from “mine” are rejected and only the new properties are considered. Seems to me like that would be a bit confusing to user to see some of their changes go through and some not…

And what if the “theirs” document was deleted - is that a possibility in your scenario ?

Hi @loongsun,
I have one question. How do you set conflict resolver? to Database instance or Replicator instance?

hi,hideki,i conflict resolver to Database instance.{ DatabaseConfiguration config = new DatabaseConfiguration(context);
// String key = “12345678123456781234567812345678”;
// EncryptionKey keyObj =new EncryptionKey(key.getBytes());
// config.setEncryptionKey(keyObj);

config.setConflictResolver(getConflictResolver());
File folder = new File(String.format("%s/SmartKitchen", Environment.getExternalStorageDirectory()));
config.setDirectory(folder);
try {
  db = new Database(DATABASE_NAME, config);
} catch (CouchbaseLiteException e) {
  e.printStackTrace();
}}

hi,priya.rajagopal,if i don’t do anything that use the default system conflict config,this issue will be more serious. Some docments will be deleteed on the Couchbase Server bucket. So some docments exsit on some devices and is nothingness on the other devices. there is no instruction how to config conflictResolver in the DB20, so i only reference todo demo’s method.

In DB 20, the default resolver on Android always selects the revision with highest generation Id as winning revision (If you want to get an overview on MVCC and revision trees, I’d recommend this blog- The conflict resolution discussion applies to CBM 1.4 - so read it for an understanding of revision trees and conflict resolution concepts.

So in DB20, deletes may not be handled as expected with the default resolver.Although I am not sure why some devices have deleted documents and some don’t.

In DB 21 (or future) , the default conflict resolver will do the following

  • Deleted revision always win
  • If no deletes, the revision with highest generation Id wins

So it may be worthwhile waiting for next DB and see if the default resolver works for you.

It really depends on your app logic. So if you have conflicting updates to a document, how do you want the conflicts to be merged ? If you provide some details on that, we can guide you. Its possible that the default resolver may suffice.

thanks to your reply。when some devices update the same document using system default conflict config, the error log is :::::::::::::::::

81/com.kitchenmanage E/Database: Failed to selectNextLeaf: doc -> com.couchbase.lite.CBLC4Doc@41d20758
LiteCoreException{domain=43, code=0, msg=null}
at com.couchbase.litecore.C4Document.selectNextLeafRevision(Native Method)
at com.couchbase.litecore.C4Document.selectNextLeafRevision(C4Document.java:121)
at com.couchbase.lite.ReadOnlyDocument.selectConflictingRevision(ReadOnlyDocument.java:187)
at com.couchbase.lite.Database.resolveConflictInDocument(Database.java:732)
at com.couchbase.lite.Replicator.documentError(Replicator.java:433)
at com.couchbase.lite.Replicator.access$100(Replicator.java:35)
at com.couchbase.lite.Replicator$1$2.run(Replicator.java:403)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5009)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)

Please add the exact steps to reproduce this to this ticket.

Does the default conflict resolver fail for your with the todo app as well ?

the exact steps are :1. run todo app on three devices and add one document 2.update that document at same time on two devices. this issue will happen.

Hi @loongsun,
I am sorry for taking the long time to fix this critical issue.
This issue will be fixed with DB022 release.
Thanks,
Hideki

谢谢hideki,这段时间来我一直关注着todo Demo的数据库版本升级,盼望着你的d022发布。这两天好像你在测试2.0.0-275版本数据库,是不是你说的d022版本数据库呀?大约还有多长时间能发布出来?

Hi @loongsun,
I can not understand the Chinese. I believe none of the team members can speak Chinese. From next time, please use English?
Based on Google Translation, I believe you are asking for the release date of DB022.
Currently, we plan to release DB022 end of next week.
DB022 will have more bug fixes on top of build 275.
Thanks!
Hideki