Hi,
I am using Couchbase Lite on C# windows service and Sync Gateway to sync device data to Couchbase Server. Below is the code to enable push replication.
private Replication GetServerPushReplication(Uri syncGateway, IEnumerable documentTypes)
{
var repl = this.Database.CreatePushReplication(syncGateway);
if (documentTypes != null)
{
repl.Filter = “db/sync-filter”;
repl.FilterParams = new Dictionary<string, object>()
{
{ “docTypes”, documentTypes.ToArray() }
};
}
repl.Continuous = false;
repl.ReplicationOptions.MaxOpenHttpConnections = 40;
repl.ReplicationOptions.Heartbeat = new TimeSpan(0, 0, 25);
repl.ReplicationOptions.MaxRevsToGetInBulk = 50;
repl.Changed += OnPushReplicationChanged;
repl.Start();
return repl;
}
I need to know which documents successfully pushed and failed. Is it possible to find in OnPushReplicationChanged event.
any help would be appreciated
Milinda
You may want to look into pendingDocumentIDs
to get Ids of documents to be pushed (although this returns nil if replication failed) and isDocumentPending
to determine if push for a specific document is pending
I have used IsDocumentPending
to check whether the document is pending or not. But still IsDocumentPending(doc)
is true after pushing into the CB server successfully in OnPushReplicationChanged
event.
protected override void OnPushReplicationChanged(object sender, ReplicationChangeEventArgs e)
{
try
{
var pendingDoc=e.Source.GetPendingDocumentIDs();
foreach (string docName in pendingDoc)
{
Couchbase.Lite.Document doc =Read(docName);
logger.Info($"{docName}: {e.Source.IsDocumentPending(doc)}");
}
}
catch (Exception ex)
{
logger.Error($"{this.DatabaseName}: Exception in Replication Change {e.Status} for {this.Mask(e.Source.RemoteUrl)}", ex);
}
}
You may want to first check the status of the replication to see if the replication did in fact complete .
public enum ReplicationStatus {
Stopped,
Offline,
Idle,
Active
}
Maybe it’s not completed and that’s why you are seeing the pending to be true.
Then document should not update in the server. Isn’t it? But I can see document is updated in the server.
Hmm…And what do you see as the status of the replication ? (Trying to narrow down where a bug , if one exists )
Below is the modified code with replication status.
protected override void OnPushReplicationChanged(object sender, ReplicationChangeEventArgs e)
{
try
{
logger.Info($"Changes: {e.ChangesCount}, Completed: {e.CompletedChangesCount}, Status: {e.Status}");
var pendingDoc=e.Source.GetPendingDocumentIDs();
foreach (string docName in pendingDoc)
{
Couchbase.Lite.Document doc =Read(docName);
logger.Info($"{docName}: {e.Source.IsDocumentPending(doc)}");
}
}
catch (Exception ex)
{
logger.Error($"{this.DatabaseName}: Exception in Replication Change {e.Status} for {this.Mask(e.Source.RemoteUrl)}", ex);
}
}
Below is the log.
Changes: 0, Completed: 0, Status: Active
sampletestdoc: True
Changes: 1, Completed: 0, Status: Active
sampletestdoc: True
Changes: 1, Completed: 1, Status: Active
Changes: 1, Completed: 1, Status: Active
Changes: 1, Completed: 1, Status: Stopped
So it looks like its working as expected. As soon as replication completes, there are no pending documents.
If I understood your original Q correctly, you wanted to know when a document has not yet been pushed . Now you can see that you can use the combination of the replication status and isDocumentPending()
to identify the same. Of course, If replication errors out, the getPendingDocumentIDs
will return nil.
That means before push to the server, we have to keep lists of pending documents in the array. After that, if e.ChangesCount>0
or Status!=Active
we have to check whether the document is pending or not.
If there is anything better than this way, please let me know.