Exemplo n.º 1
0
        // Get a bunch of revisions in one bulk request. Will use _bulk_get if possible.
        protected internal void PullBulkRevisions(IList <RevisionInternal> bulkRevs)
        {
            int nRevs = bulkRevs.Count;

            if (nRevs == 0)
            {
                return;
            }
            Log.V(Log.TagSync, "%s bulk-fetching %d remote revisions...", this, nRevs);
            Log.V(Log.TagSync, "%s bulk-fetching remote revisions: %s", this, bulkRevs);
            if (!canBulkGet)
            {
                PullBulkWithAllDocs(bulkRevs);
                return;
            }
            Log.V(Log.TagSync, "%s: POST _bulk_get", this);
            IList <RevisionInternal> remainingRevs = new AList <RevisionInternal>(bulkRevs);

            Log.V(Log.TagSync, "%s | %s: pullBulkRevisions() calling asyncTaskStarted()", this
                  , Sharpen.Thread.CurrentThread());
            AsyncTaskStarted();
            ++httpConnectionCount;
            BulkDownloader dl;

            try
            {
                dl = new BulkDownloader(workExecutor, clientFactory, remote, bulkRevs, db, this.requestHeaders
                                        , new _BulkDownloaderDocumentBlock_506(this, remainingRevs), new _RemoteRequestCompletionBlock_537
                                            (this, remainingRevs));
            }
            catch (Exception)
            {
                // Got a revision!
                // Find the matching revision in 'remainingRevs' and get its sequence:
                // Add to batcher ... eventually it will be fed to -insertRevisions:.
                // The entire _bulk_get is finished:
                // Note that we've finished this task:
                // Start another task if there are still revisions waiting to be pulled:
                return;
            }
            dl.SetAuthenticator(GetAuthenticator());
            remoteRequestExecutor.Execute(dl);
        }
Exemplo n.º 2
0
        // Get a bunch of revisions in one bulk request. Will use _bulk_get if possible.
        private void PullBulkRevisions(IList <RevisionInternal> bulkRevs)
        {
            var nRevs = bulkRevs == null ? 0 : bulkRevs.Count;

            if (nRevs == 0)
            {
                return;
            }

            Log.To.Sync.I(TAG, "{0} bulk-fetching {1} remote revisions...", ReplicatorID, nRevs);
            if (!_canBulkGet)
            {
                PullBulkWithAllDocs(bulkRevs);
                return;
            }

            Log.To.SyncPerf.I(TAG, "{0} bulk-getting {1} remote revisions...", ReplicatorID, nRevs);
            var            remainingRevs = new List <RevisionInternal>(bulkRevs);
            BulkDownloader dl            = new BulkDownloader(new BulkDownloaderOptions {
                ClientFactory  = ClientFactory,
                DatabaseUri    = RemoteUrl,
                Revisions      = bulkRevs,
                Database       = LocalDatabase,
                RequestHeaders = RequestHeaders,
                RetryStrategy  = ReplicationOptions.RetryStrategy,
                CookieStore    = CookieContainer
            });

            dl.DocumentDownloaded += (sender, args) =>
            {
                var props = args.DocumentProperties;

                var rev = props.CblID() != null
                    ? new RevisionInternal(props)
                    : new RevisionInternal(props.CblID(), props.CblRev(), false);


                var pos = remainingRevs.IndexOf(rev);
                if (pos > -1)
                {
                    rev.Sequence = remainingRevs[pos].Sequence;
                    remainingRevs.RemoveAt(pos);
                }
                else
                {
                    Log.To.Sync.W(TAG, "Received unexpected rev {0}; ignoring", rev);
                    return;
                }

                if (props.CblID() != null)
                {
                    // Add to batcher ... eventually it will be fed to -insertRevisions:.
                    QueueDownloadedRevision(rev);
                }
                else
                {
                    var status = StatusFromBulkDocsResponseItem(props);
                    Log.To.Sync.W(TAG, "Error downloading {0}", rev);
                    var error = new CouchbaseLiteException(status.Code);
                    LastError = error;
                    RevisionFailed();
                    SafeIncrementCompletedChangesCount();
                    if (IsDocumentError(error))
                    {
                        _pendingSequences.RemoveSequence(rev.Sequence);
                    }
                }
            };

            dl.Complete += (sender, args) =>
            {
                if (args != null && args.Error != null)
                {
                    RevisionFailed();
                    if (remainingRevs.Count == 0)
                    {
                        LastError = args.Error;
                    }
                }
                else if (remainingRevs.Count > 0)
                {
                    Log.To.Sync.W(TAG, "{0} revs not returned from _bulk_get: {1}",
                                  remainingRevs.Count, remainingRevs);
                    for (int i = 0; i < remainingRevs.Count; i++)
                    {
                        var rev = remainingRevs[i];
                        if (ShouldRetryDownload(rev.DocID))
                        {
                            _bulkRevsToPull.Add(remainingRevs[i]);
                        }
                        else
                        {
                            LastError = args.Error;
                            SafeIncrementCompletedChangesCount();
                        }
                    }
                }

                SafeAddToCompletedChangesCount(remainingRevs.Count);
                LastSequence = _pendingSequences.GetCheckpointedValue();
                Misc.SafeDispose(ref dl);

                PullRemoteRevisions();
            };

            dl.Authenticator = Authenticator;
            WorkExecutor.StartNew(dl.Start, CancellationTokenSource.Token, TaskCreationOptions.None, WorkExecutor.Scheduler);
        }
Exemplo n.º 3
0
        // Get a bunch of revisions in one bulk request. Will use _bulk_get if possible.
        internal void PullBulkRevisions(IList <RevisionInternal> bulkRevs)
        {
            var nRevs = bulkRevs.Count;

            if (nRevs == 0)
            {
                return;
            }

            Log.V(Tag, "{0} bulk-fetching {1} remote revisions...", this, nRevs);
            Log.V(Tag, "{0} bulk-fetching remote revisions: {1}", this, bulkRevs);

            if (!canBulkGet)
            {
                PullBulkWithAllDocs(bulkRevs);
                return;
            }

            Log.V(Tag, "POST _bulk_get");
            var remainingRevs = new List <RevisionInternal>(bulkRevs);

            Log.V(Tag, "PullBulkRevisions() calling AsyncTaskStarted()");
            AsyncTaskStarted();

            ++httpConnectionCount;
            BulkDownloader dl;

            try
            {
                dl = new BulkDownloader(WorkExecutor, clientFactory, RemoteUrl, bulkRevs, LocalDatabase, RequestHeaders);
                // , new _BulkDownloaderDocumentBlock_506(this, remainingRevs), new _RemoteRequestCompletionBlock_537(this, remainingRevs)
                // TODO: add event handles for completion and documentdownloaded.
                dl.DocumentDownloaded += (sender, e) =>
                {
                    var props = e.DocumentProperties;

                    var rev = props.Get("_id") != null
                        ? new RevisionInternal(props)
                        : new RevisionInternal((string)props.Get("id"), (string)props.Get("rev"), false);

                    Log.D(Tag, "Document downloaded! {0}", rev);

                    var pos = remainingRevs.IndexOf(rev);
                    if (pos > -1)
                    {
                        rev.SetSequence(remainingRevs[pos].GetSequence());
                        remainingRevs.Remove(pos);
                    }
                    else
                    {
                        Log.W(Tag, "Received unexpected rev rev");
                    }
                    if (props.Get("_id") != null)
                    {
                        QueueDownloadedRevision(rev);
                    }
                    else
                    {
                        var status = StatusFromBulkDocsResponseItem(props);
                        SetLastError(new CouchbaseLiteException(status.GetCode()));
                        RevisionFailed();
                        SafeIncrementCompletedChangesCount();
                    }
                };

                dl.Complete += (sender, args) =>
                {
                    if (args != null && args.Error != null)
                    {
                        SetLastError(args.Error);
                        RevisionFailed();
                        SafeAddToCompletedChangesCount(remainingRevs.Count);
                    }

                    Log.V(Tag, "PullBulkRevisions.Completion event handler calling AsyncTaskFinished()");
                    AsyncTaskFinished(1);

                    --httpConnectionCount;

                    PullRemoteRevisions();
                };
            }
            catch (Exception)
            {
                // Got a revision!
                // Find the matching revision in 'remainingRevs' and get its sequence:
                // Add to batcher ... eventually it will be fed to -insertRevisions:.
                // The entire _bulk_get is finished:
                // Note that we've finished this task:
                // Start another task if there are still revisions waiting to be pulled:
                return;
            }
            dl.Authenticator = Authenticator;
            WorkExecutor.StartNew(dl.Run, CancellationTokenSource.Token, TaskCreationOptions.LongRunning, WorkExecutor.Scheduler);
//            dl.Run();
        }
Exemplo n.º 4
0
        // Get a bunch of revisions in one bulk request. Will use _bulk_get if possible.
        private void PullBulkRevisions(IList <RevisionInternal> bulkRevs)
        {
            var nRevs = bulkRevs == null ? 0 : bulkRevs.Count;

            if (nRevs == 0)
            {
                return;
            }

            Log.D(TAG, "{0} bulk-fetching {1} remote revisions...", this, nRevs);
            Log.V(TAG, "{0} bulk-fetching remote revisions: {1}", this, bulkRevs);

            if (!_canBulkGet)
            {
                PullBulkWithAllDocs(bulkRevs);
                return;
            }

            Log.V(TAG, "POST _bulk_get");
            var remainingRevs = new List <RevisionInternal>(bulkRevs);

            ++_httpConnectionCount;
            BulkDownloader dl;

            try
            {
                dl = new BulkDownloader(WorkExecutor, ClientFactory, RemoteUrl, bulkRevs, LocalDatabase, RequestHeaders);
                dl.DocumentDownloaded += (sender, args) =>
                {
                    var props = args.DocumentProperties;

                    var rev = props.Get("_id") != null
                        ? new RevisionInternal(props)
                        : new RevisionInternal(props.GetCast <string> ("id"), props.GetCast <string> ("rev"), false);


                    var pos = remainingRevs.IndexOf(rev);
                    if (pos > -1)
                    {
                        rev.SetSequence(remainingRevs[pos].GetSequence());
                        remainingRevs.RemoveAt(pos);
                    }
                    else
                    {
                        Log.W(TAG, "Received unexpected rev {0}; ignoring", rev);
                        return;
                    }

                    if (props.GetCast <string>("_id") != null)
                    {
                        // Add to batcher ... eventually it will be fed to -insertRevisions:.
                        QueueDownloadedRevision(rev);
                    }
                    else
                    {
                        var status = StatusFromBulkDocsResponseItem(props);
                        LastError = new CouchbaseLiteException(status.Code);
                        RevisionFailed();
                        SafeIncrementCompletedChangesCount();
                    }
                };

                dl.Complete += (sender, args) =>
                {
                    if (args != null && args.Error != null)
                    {
                        RevisionFailed();
                        if (remainingRevs.Count == 0)
                        {
                            LastError = args.Error;
                        }
                    }
                    else if (remainingRevs.Count > 0)
                    {
                        Log.W(TAG, "{0} revs not returned from _bulk_get: {1}",
                              remainingRevs.Count, remainingRevs);
                        for (int i = 0; i < remainingRevs.Count; i++)
                        {
                            var rev = remainingRevs[i];
                            if (ShouldRetryDownload(rev.GetDocId()))
                            {
                                _bulkRevsToPull.Add(remainingRevs[i]);
                            }
                            else
                            {
                                LastError = args.Error;
                                SafeIncrementCompletedChangesCount();
                            }
                        }
                    }

                    SafeAddToCompletedChangesCount(remainingRevs.Count);

                    --_httpConnectionCount;

                    PullRemoteRevisions();
                };
            } catch (Exception) {
                return;
            }

            dl.Authenticator = Authenticator;
            WorkExecutor.StartNew(dl.Run, CancellationTokenSource.Token, TaskCreationOptions.None, WorkExecutor.Scheduler);
        }