Beispiel #1
0
        private void StartChangeTracker()
        {
            Log.D(TAG, "starting ChangeTracker with since = " + LastSequence);

            var mode = Continuous
                ? ChangeTrackerMode.LongPoll
                : ChangeTrackerMode.OneShot;

            _changeTracker = new ChangeTracker(RemoteUrl, mode, LastSequence, true, this, WorkExecutor);
            _changeTracker.Authenticator = Authenticator;
            if (DocIds != null)
            {
                if (ServerType != null && ServerType.Name == "CouchDB")
                {
                    _changeTracker.SetDocIDs(DocIds.ToList());
                }
                else
                {
                    Log.W(TAG, "DocIds parameter only supported on CouchDB");
                }
            }

            if (Filter != null)
            {
                _changeTracker.SetFilterName(Filter);
                if (FilterParams != null)
                {
                    _changeTracker.SetFilterParams(FilterParams.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
                }
            }

            _changeTracker.UsePost = CheckServerCompatVersion("0.93");
            _changeTracker.Start();
        }
Beispiel #2
0
        private void StartChangeTracker()
        {
            var mode         = ChangeTrackerMode.OneShot;
            var pollInterval = ReplicationOptions.PollInterval;

            if (Continuous && pollInterval == TimeSpan.Zero && ReplicationOptions.UseWebSocket)
            {
                mode = ChangeTrackerMode.WebSocket;
            }

            Log.To.Sync.V(TAG, "{0} starting ChangeTracker: mode={0} since={1}", this, mode, LastSequence);
            var initialSync          = LocalDatabase.IsOpen && LocalDatabase.GetDocumentCount() == 0;
            var changeTrackerOptions = new ChangeTrackerOptions {
                DatabaseUri      = RemoteUrl,
                Mode             = mode,
                IncludeConflicts = true,
                LastSequenceID   = LastSequence,
                Client           = this,
                RetryStrategy    = ReplicationOptions.RetryStrategy,
                WorkExecutor     = WorkExecutor,
            };

            _changeTracker               = ChangeTrackerFactory.Create(changeTrackerOptions);
            _changeTracker.ActiveOnly    = initialSync;
            _changeTracker.Authenticator = Authenticator;
            _changeTracker.Continuous    = Continuous;
            _changeTracker.PollInterval  = pollInterval;
            _changeTracker.Heartbeat     = ReplicationOptions.Heartbeat;
            if (DocIds != null)
            {
                if (ServerType != null && ServerType.Name == "CouchDB")
                {
                    _changeTracker.DocIDs = DocIds.ToList();
                }
                else
                {
                    Log.To.Sync.W(TAG, "DocIds parameter only supported on CouchDB");
                }
            }

            if (Filter != null)
            {
                _changeTracker.FilterName = Filter;
                if (FilterParams != null)
                {
                    _changeTracker.FilterParameters = FilterParams.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                }
            }

            if (ServerType != null)
            {
                _changeTracker.ServerType = ServerType;
            }

            _changeTracker.Start();
        }
Beispiel #3
0
        private void StartChangeTracker()
        {
            var mode         = ChangeTrackerMode.OneShot;
            var pollInterval = ReplicationOptions.PollInterval;

            if (Continuous && pollInterval == TimeSpan.Zero && ReplicationOptions.UseWebSocket)
            {
                mode = ChangeTrackerMode.WebSocket;
            }

            _canBulkGet = mode == ChangeTrackerMode.WebSocket;
            Log.To.Sync.V(TAG, "{0} starting ChangeTracker: mode={0} since={1}", this, mode, LastSequence);
            var initialSync          = LocalDatabase.IsOpen && LocalDatabase.GetDocumentCount() == 0;
            var changeTrackerOptions = new ChangeTrackerOptions {
                DatabaseUri      = RemoteUrl,
                Mode             = mode,
                IncludeConflicts = true,
                LastSequenceID   = LastSequence,
                Client           = this,
                RemoteSession    = _remoteSession,
                RetryStrategy    = ReplicationOptions.RetryStrategy,
                WorkExecutor     = WorkExecutor,
                UsePost          = CheckServerCompatVersion("0.9.3")
            };

            _changeTracker              = ChangeTrackerFactory.Create(changeTrackerOptions);
            _changeTracker.ActiveOnly   = initialSync;
            _changeTracker.Continuous   = Continuous;
            _changeTracker.PollInterval = pollInterval;
            _changeTracker.Heartbeat    = ReplicationOptions.Heartbeat;
            _changeTracker.DocIDs       = DocIds?.ToList();

            if (Filter != null)
            {
                _changeTracker.FilterName = Filter;
                if (FilterParams != null)
                {
                    _changeTracker.FilterParameters = FilterParams.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                }
            }

            _changeTracker.Start();
        }
Beispiel #4
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);
                }
            }
        }
        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;
            }
        }
Beispiel #6
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);
                }
            }
        }