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