Correct way to restart a Replication?

I’m using Couchbase Lite .NET 1.2. SystemSQLite storage. Sync Gateway 1.1 with walrus. Observed behavior with Xamarin.Android, but iOS will matter as well.

At startup, my app starts continuous push and pull replications.

Later, if the user decides to login (with Facebook), I want to change the Replications to include those auth credentials. That code looks something like this:

var auth = Couchbase.Lite.Auth.AuthenticatorFactory.CreateFacebookAuthenticator (_facebookToken);
_pull.Authenticator = auth;
_push.Authenticator = auth;

after which I do:

_pull.Restart ();
_push.Restart ();

but in the application output I see:

Replication: Not starting becuse identical puller already exists
Replication: Not starting becuse identical pusher already exists

And after that, the replications have stopped working.

I’ve tried using Stop followed by Start, instead of Restart. Similar results.

I expect the need to make other kinds of changes to the Replication as well. For example, my app will sometimes realize it needs to add a channel.

Am I doing something wrong? Should I be discarding the Replication objects and creating new ones? Or simply adding new ones to the ones already there?

Thanks in advance.

You aren’t doing anything wrong, and I can’t reproduce this but I think I have an idea of what is happening. It seems like there is a race condition in the restart logic.

The restart will call Stop() and then wait for the replicator to transition into the Stopped state before then calling Start() again. The problem is there is a guard in Start() against starting more than one instance of an “identical” replicator. Changing the authentication scheme will not affect the signature of the authenticator and so the library views them as identical. The replicator will eventually be removed but that is the race (between the old one getting removed from the list of known replications and the new one getting added).

The good news is that there is a workaround you can do. It’s not great but it involves adding an artificial delay between when you call stop and when you call start. You can watch the Changed property to see when the replication changed to Stopped and after that if you wait a couple seconds you will be able to start it again. I know this is not an acceptable solution, and I will have a fix for this ready today.

I’ve moved the removal of the old replication to a more deterministic place in commit 2a51e0f. I can’t give a firm estimate as to when this will be available in a packaged form, but there is a lot of work right now going into biweekly prerelease cycles and I hope they will start soon.

I realized I forgot to address another part of your question: Changing channels will not have the same problem as you experience with changing authenticators. Changing the channel will change the signature of the replicator and the library will consider it a different replication.

Cool. Thanks very much.