I’ve got something weird with the sync engine when there is an app crash.
It’s been around for a long time, but was rare enough that I ignored it.
It turns out this happens most of the time if the app crashes during startup.
Environmental Details:
- Client: MacOS Ventura 13.5
- Language/Framework: C#, .Net Core 7
- CB Lib: Couchbase.Lite 3.1.1, Couchbase.Lite.Support.NetDesktop 3.1.1
How to reproduce:
- Have a cb database with an account with a reasonable amount of data (in my case 94 MB with 260 documents). I can reproduce this with less - it just needs to be enough to take time to sync.
- Start up my app on a machine. First time run so there is no local db.
- Collect login credentials.
- Local DB is created. The sync engine starts. I can see syncing start, and data begins to arrive.
- Kill the app (using kill -9 or in the debugger).
Now restart the app.
- Collect login credentials
- The sync engine starts.
- The sync engine pulls no data, it sends a SyncUpdate message of “Idle”.
There seems to be no way to tell the difference between an incomplete sync and a normal complete sync, that is I don’t get any indication of the failure. Further the only way to fix this is to delete the local db and restart the sync from scratch. That is, restarting the app doesn’t fix this. Once it believes sync is complete, it is always complete.
Logging
I have been collecting DB logs using a class that implements ILogger. In my case, I just dump the log entries into nlog using a shameless copy of your sample code:
class DBSyncLogger : Couchbase.Lite.Logging.ILogger
{
private static Logger log = LogManager.GetCurrentClassLogger();
public Couchbase.Lite.Logging.LogLevel Level { get; set; }
public void Reset()
{
}
public void Log(Couchbase.Lite.Logging.LogLevel level, LogDomain domain, string message)
{
switch (level)
{
case Couchbase.Lite.Logging.LogLevel.Info:
log.Info(message);
break;
case Couchbase.Lite.Logging.LogLevel.Error:
log.Error(message);
break;
case Couchbase.Lite.Logging.LogLevel.Warning:
log.Warn(message);
break;
case Couchbase.Lite.Logging.LogLevel.Debug:
log.Debug(message);
break;
case Couchbase.Lite.Logging.LogLevel.Verbose:
log.Trace(message);
break;
}
}
}
I start the logging using the following code:
#if ENABLEDBLOGGING
Database.Log.Custom = new DBSyncLogger { Level = Couchbase.Lite.Logging.LogLevel.Warning };
Database.Log.Console.Domains = LogDomain.All;
Database.Log.Console.Level = Couchbase.Lite.Logging.LogLevel.Verbose;
#endif
I ran my app, killed it, then ran it again (as outlined above).
I have attached the output of the second run (with as much extraneous logging information removed). You can see the sync being started up, the replicator connecting to the remote end, it doing a few reads/writes and SyncUpdate messages (to my code), then it goes into idle state with hundreds of docs unsynced.
I sure hope I’m doing something wrong during sync. Here is the code that kicks off the sync:
this.syncCallBack = syncCallBack;
var config = AppConfig.Instance;
var url = new Uri(config.sync_url);
var target = new URLEndpoint(url);
var auth = new BasicAuthenticator(id, secure_server_password);
var collection = database.GetCollection("_default");
var collection_configuration = new CollectionConfiguration()
{
ConflictResolver = new SyncConflictResolver()
};
var sync_config = new ReplicatorConfiguration(target)
{
ReplicatorType = ReplicatorType.PushAndPull,
Continuous = true,
Authenticator = auth,
//EnableAutoPurge = true
};
sync_config.AddCollection(collection, collection_configuration);
replicator = new Replicator(sync_config);
listenerToken = replicator.AddChangeListener(SyncStatusUpdate);
log.Debug("StartSyncAgent: Using url: {0}, id: {1}".Fmt(url, id));
replicator.Start();
Any thoughts/comments would be most appreciated.
p.s. I see this sometimes later during application execution. That is, the app starts and completes first sync. Then later the app crashes (presumably during a later sync), then it never syncs any more documents, it just says idle. I think this is the same instance of the problem, but haven’t proved it.
p.p.s I’m not seeing any errors that could indicate a locally corrupted db.
p.p.p.s if there are no crashes, then syncing works fine. Most of the time if there is an app crash after the initial sync completes (and perhaps when syncing isn’t happening), then syncing continues to work fine.
Thank you
Paul.