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 SortedSet <long>();
            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);
            }

            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 #2
0
        public override void BeginReplicating()
        {
            Log.D(Log.TagSync, "%s: beginReplicating() called", this);
            // 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(Log.TagSync, "%s: creatingTarget == true, doing nothing", this);
                return;
            }
            pendingSequences = Sharpen.Collections.SynchronizedSortedSet(new TreeSet <long>());
            try
            {
                maxPendingSequence = long.Parse(lastSequence);
            }
            catch (FormatException)
            {
                Log.W(Log.TagSync, "Error converting lastSequence: %s to long.  Using 0", lastSequence
                      );
                maxPendingSequence = System.Convert.ToInt64(0);
            }
            if (filterName != null)
            {
                filter = db.GetFilter(filterName);
            }
            if (filterName != null && filter == null)
            {
                Log.W(Log.TagSync, "%s: No ReplicationFilter registered for filter '%s'; ignoring"
                      , this, filterName);
            }
            // Process existing changes since the last push:
            long lastSequenceLong = 0;

            if (lastSequence != null)
            {
                lastSequenceLong = long.Parse(lastSequence);
            }
            ChangesOptions options = new ChangesOptions();

            options.SetIncludeConflicts(true);
            RevisionList changes = db.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;
                db.AddChangeListener(this);
            }
        }
        public 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.)
            Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": beginReplicating() called"
                  );
            if (creatingTarget)
            {
                Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": creatingTarget == true, doing nothing"
                      );
                return;
            }
            else
            {
                Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": creatingTarget != true, continuing"
                      );
            }
            if (filterName != null)
            {
                filter = db.GetFilter(filterName);
            }
            if (filterName != null && filter == null)
            {
                Log.W(Database.Tag, string.Format("%s: No ReplicationFilter registered for filter '%s'; ignoring"
                                                  , this, filterName));
            }
            // Process existing changes since the last push:
            long lastSequenceLong = 0;

            if (lastSequence != null)
            {
                lastSequenceLong = long.Parse(lastSequence);
            }
            ChangesOptions options = new ChangesOptions();

            options.SetIncludeConflicts(true);
            RevisionList changes = db.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;
                db.AddChangeListener(this);
                Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": pusher.beginReplicating() calling asyncTaskStarted()"
                      );
                AsyncTaskStarted();
            }
        }
        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;
            }
        }
        /// <summary>
        /// Returns a sorted list of changes made to documents in the database, in time order of application.
        /// </summary>
        /// <returns>The response state for further HTTP processing</returns>
        /// <param name="context">The context of the Couchbase Lite HTTP request</param>
        /// <remarks>
        /// http://docs.couchdb.org/en/latest/api/database/changes.html#get--db-_changes
        /// <remarks>
        public static ICouchbaseResponseState GetChanges(ICouchbaseListenerContext context)
        {
            DBMonitorCouchbaseResponseState responseState = new DBMonitorCouchbaseResponseState();

            var responseObject = PerformLogicWithDatabase(context, true, db =>
            {
                var response           = context.CreateResponse();
                responseState.Response = response;
                if (context.ChangesFeedMode < ChangesFeedMode.Continuous)
                {
                    if (context.CacheWithEtag(db.LastSequenceNumber.ToString()))
                    {
                        response.InternalStatus = StatusCode.NotModified;
                        return(response);
                    }
                }

                var options                      = new ChangesOptions();
                responseState.Db                 = db;
                responseState.ContentOptions     = context.ContentOptions;
                responseState.ChangesFeedMode    = context.ChangesFeedMode;
                responseState.ChangesIncludeDocs = context.GetQueryParam <bool>("include_docs", bool.TryParse, false);
                options.SetIncludeDocs(responseState.ChangesIncludeDocs);
                responseState.ChangesIncludeConflicts = context.GetQueryParam("style") == "all_docs";
                options.SetIncludeConflicts(responseState.ChangesIncludeConflicts);
                options.SetContentOptions(context.ContentOptions);
                options.SetSortBySequence(!options.IsIncludeConflicts());
                options.SetLimit(context.GetQueryParam <int>("limit", int.TryParse, options.GetLimit()));
                int since = context.GetQueryParam <int>("since", int.TryParse, 0);

                string filterName = context.GetQueryParam("filter");
                if (filterName != null)
                {
                    Status status = new Status();
                    responseState.ChangesFilter = db.GetFilter(filterName, status);
                    if (responseState.ChangesFilter == null)
                    {
                        return(context.CreateResponse(status.Code));
                    }

                    responseState.FilterParams = context.GetQueryParams();
                }


                RevisionList changes = db.ChangesSince(since, options, responseState.ChangesFilter, responseState.FilterParams);
                if ((context.ChangesFeedMode >= ChangesFeedMode.Continuous) ||
                    (context.ChangesFeedMode == ChangesFeedMode.LongPoll && changes.Count == 0))
                {
                    // Response is going to stay open (continuous, or hanging GET):
                    response.Chunked = true;
                    if (context.ChangesFeedMode == ChangesFeedMode.EventSource)
                    {
                        response["Content-Type"] = "text/event-stream; charset=utf-8";
                    }

                    if (context.ChangesFeedMode >= ChangesFeedMode.Continuous)
                    {
                        response.WriteHeaders();
                        foreach (var rev in changes)
                        {
                            response.SendContinuousLine(ChangesDictForRev(rev, responseState), context.ChangesFeedMode);
                        }
                    }

                    responseState.SubscribeToDatabase(db);
                    string heartbeatParam = context.GetQueryParam("heartbeat");
                    if (heartbeatParam != null)
                    {
                        int heartbeat;
                        if (!int.TryParse(heartbeatParam, out heartbeat) || heartbeat <= 0)
                        {
                            responseState.IsAsync = false;
                            return(context.CreateResponse(StatusCode.BadParam));
                        }

                        heartbeat = Math.Min(heartbeat, MIN_HEARTBEAT);
                        string heartbeatResponse = context.ChangesFeedMode == ChangesFeedMode.EventSource ? "\n\n" : "\r\n";
                        responseState.StartHeartbeat(heartbeatResponse, heartbeat);
                    }

                    return(context.CreateResponse());
                }
                else
                {
                    if (responseState.ChangesIncludeConflicts)
                    {
                        response.JsonBody = new Body(ResponseBodyForChanges(changes, since, options.GetLimit(), responseState));
                    }
                    else
                    {
                        response.JsonBody = new Body(ResponseBodyForChanges(changes, since, responseState));
                    }

                    return(response);
                }
            });

            responseState.Response = responseObject;
            return(responseState);
        }