internal override void BeginReplicating() { // If we're still waiting to create the remote db, do nothing now. (This method will be // re-invoked after that request finishes; see maybeCreateRemoteDB() above.) if (_creatingTarget) { Log.To.Sync.D(TAG, "creatingTarget == true, doing nothing"); return; } _pendingSequences = new SortedDictionary <long, int>(); if (!Int64.TryParse(LastSequence, out _maxPendingSequence)) { Log.To.Sync.W(TAG, "{0} is not a valid last sequence, using 0", LastSequence); _maxPendingSequence = 0; } if (Filter != null) { _filter = LocalDatabase.GetFilter(Filter); } else { // If not filter function was provided, but DocIds were // specified, then only push the documents listed in the // DocIds property. It is assumed that if the users // specified both a filter name and doc ids that their // custom filter function will handle that. This is // consistent with the iOS behavior. if (DocIds != null && DocIds.Any()) { _filter = (rev, filterParams) => DocIds.Contains(rev.Document.Id); } } if (Filter != null && _filter == null) { Log.To.Sync.W(TAG, "{0}: No ReplicationFilter registered for filter '{1}'; ignoring", this, Filter); } // Process existing changes since the last push: long lastSequenceLong = 0; if (LastSequence != null) { lastSequenceLong = long.Parse(LastSequence); } if (ReplicationOptions.PurgePushed) { _purgeQueue = new Batcher <RevisionInternal>(new BatcherOptions <RevisionInternal> { WorkExecutor = WorkExecutor, Capacity = EphemeralPurgeBatchSize, Delay = EphemeralPurgeDelay, Processor = PurgeRevs, TokenSource = CancellationTokenSource }); } // Now listen for future changes (in continuous mode): // Note: This needs to happen before adding the observer // or else there is a race condition. // A document could be added between the call to // ChangesSince and adding the observer, which would result // in a document being skipped if (Continuous) { _observing = true; LocalDatabase.Changed += OnChanged; } var options = ChangesOptions.Default; options.IncludeConflicts = true; var changes = LocalDatabase.ChangesSinceStreaming(lastSequenceLong, options, _filter, FilterParams); bool hasItems = changes.Any(); foreach (var change in changes) { Batcher.QueueObject(change); if (Status == ReplicationStatus.Stopped) { Batcher.Clear(); return; } } if (hasItems) { Batcher.Flush(); } if (Continuous) { if (!hasItems) { Log.To.Sync.V(TAG, "No changes to push, switching to idle..."); FireTrigger(ReplicationTrigger.WaitingForChanges); } } else { if (!hasItems) { Log.To.Sync.V(TAG, "No changes to push, firing StopGraceful..."); FireTrigger(ReplicationTrigger.StopGraceful); } } }