Esempio n. 1
0
        internal override void BeginReplicating()
        {
            Log.D(Tag, "beginReplicating() called");

            // 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.D(Tag, "creatingTarget == true, doing nothing");
                return;
            }

            pendingSequences = new SortedDictionary <long, int>();
            try
            {
                maxPendingSequence = Int64.Parse(LastSequence);
            }
            catch (Exception e)
            {
                Log.W(Tag, "Error converting lastSequence: " + LastSequence + " to long. Using 0");
                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.W(Tag, string.Format("{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);
            }

            var options = new ChangesOptions();

            options.SetIncludeConflicts(true);
            var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, filter);

            if (changes.Count > 0)
            {
                Batcher.QueueObjects(changes);
                Batcher.Flush();
            }

            // Now listen for future changes (in continuous mode):
            if (continuous)
            {
                observing              = true;
                LocalDatabase.Changed += OnChanged;
            }
        }
Esempio n. 2
0
        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>(WorkExecutor, EphemeralPurgeBatchSize,
                                                             EphemeralPurgeDelay, (revs) =>
                {
                    Log.To.Sync.I(TAG, "Purging {0} docs ('purgePushed' option)", revs.Count);
                    var toPurge = new Dictionary <string, IList <string> >();
                    foreach (var rev in revs)
                    {
                        toPurge[rev.DocID] = new List <string> {
                            rev.RevID
                        };
                    }

                    var localDb = LocalDatabase;
                    if (localDb != null && localDb.IsOpen)
                    {
                        var storage = localDb.Storage;
                        if (storage != null && storage.IsOpen)
                        {
                            storage.PurgeRevisions(toPurge);
                        }
                        else
                        {
                            Log.To.Sync.W(TAG, "{0} storage is closed, cannot purge...", localDb);
                        }
                    }
                    else
                    {
                        Log.To.Sync.W(TAG, "Local database is closed or null, cannot purge...");
                    }
                }, 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.ChangesSince(lastSequenceLong, options, _filter, FilterParams);

            if (changes.Count > 0)
            {
                Batcher.QueueObjects(changes);
                Batcher.Flush();
            }

            if (Continuous)
            {
                if (changes.Count == 0)
                {
                    Log.To.Sync.V(TAG, "No changes to push, switching to idle...");
                    FireTrigger(ReplicationTrigger.WaitingForChanges);
                }
            }
            else
            {
                if (changes.Count == 0)
                {
                    Log.To.Sync.V(TAG, "No changes to push, firing StopGraceful...");
                    FireTrigger(ReplicationTrigger.StopGraceful);
                }
            }
        }
Esempio n. 3
0
        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);
            }

            // 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.ChangesSince(lastSequenceLong, options, _filter, FilterParams);

            if (changes.Count > 0)
            {
                Batcher.QueueObjects(changes);
                Batcher.Flush();
            }

            if (Continuous)
            {
                if (changes.Count == 0)
                {
                    FireTrigger(ReplicationTrigger.WaitingForChanges);
                }
            }
            else
            {
                if (changes.Count == 0)
                {
                    FireTrigger(ReplicationTrigger.StopGraceful);
                }
            }
        }