コード例 #1
0
        protected async Task InitializeAsync(
            string collectionRid,
            List <Range <string> > queryRanges,
            Func <DocumentProducer <T>, int> taskPriorityFunc,
            IReadOnlyList <PartitionKeyRange> partitionKeyRanges,
            int initialPageSize,
            SqlQuerySpec querySpecForInit,
            Dictionary <string, string> targetRangeToContinuationMap,
            CancellationToken token)
        {
            CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

            INameValueCollection requestHeaders = await this.CreateCommonHeadersAsync(this.GetFeedOptions(null));

            DefaultTrace.TraceInformation(string.Format(
                                              CultureInfo.InvariantCulture,
                                              "{0}, CorrelatedActivityId: {1} | Parallel~ContextBase.InitializeAsync, MaxBufferedItemCount: {2}, Target PartitionKeyRange Count: {3}, MaximumConcurrencyLevel: {4}, DocumentProducer Initial Page Size {5}",
                                              DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                                              this.CorrelatedActivityId,
                                              this.actualMaxBufferedItemCount,
                                              partitionKeyRanges.Count,
                                              this.TaskScheduler.MaximumConcurrencyLevel,
                                              initialPageSize));

            foreach (PartitionKeyRange range in partitionKeyRanges)
            {
                string initialContinuationToken = (targetRangeToContinuationMap != null && targetRangeToContinuationMap.ContainsKey(range.Id)) ? targetRangeToContinuationMap[range.Id] : null;

                this.DocumentProducers.Add(new DocumentProducer <T>(
                                               this.TaskScheduler,
                                               (continuationToken, pageSize) =>
                {
                    INameValueCollection headers = requestHeaders.Clone();
                    headers[HttpConstants.HttpHeaders.Continuation] = continuationToken;
                    headers[HttpConstants.HttpHeaders.PageSize]     = pageSize.ToString(CultureInfo.InvariantCulture);
                    return(this.CreateDocumentServiceRequest(
                               headers,
                               querySpecForInit,
                               range,
                               collectionRid));
                },
                                               range,
                                               taskPriorityFunc,
                                               this.ExecuteRequestAsync <T>,
                                               () => new NonRetriableInvalidPartitionExceptionRetryPolicy(collectionCache, this.Client.RetryPolicy.GetRequestPolicy()),
                                               this.OnDocumentProducerCompleteFetching,
                                               this.CorrelatedActivityId,
                                               initialPageSize,
                                               initialContinuationToken));

                if (!string.IsNullOrEmpty(initialContinuationToken))
                {
                    this.CurrentContinuationTokens[this.DocumentProducers[this.DocumentProducers.Count - 1]] = initialContinuationToken;
                }
            }
        }
コード例 #2
0
 internal DocumentFeedResponse(
     IEnumerable <T> result,
     int count,
     INameValueCollection responseHeaders,
     bool useETagAsContinuation = false,
     IReadOnlyDictionary <string, QueryMetrics> queryMetrics = null,
     IClientSideRequestStatistics requestStats = null,
     string disallowContinuationTokenMessage   = null,
     long responseLengthBytes = 0)
     : this(result)
 {
     this.Count                            = count;
     this.responseHeaders                  = (INameValueCollection)responseHeaders.Clone();
     this.usageHeaders                     = new Dictionary <string, long>();
     this.quotaHeaders                     = new Dictionary <string, long>();
     this.useETagAsContinuation            = useETagAsContinuation;
     this.queryMetrics                     = queryMetrics;
     this.disallowContinuationTokenMessage = disallowContinuationTokenMessage;
     this.ResponseLengthBytes              = responseLengthBytes;
 }
コード例 #3
0
        /// <summary>
        /// Initializes cross partition query execution context by initializing the necessary document producers.
        /// </summary>
        /// <param name="collectionRid">The collection to drain from.</param>
        /// <param name="partitionKeyRanges">The partitions to target.</param>
        /// <param name="initialPageSize">The page size to start the document producers off with.</param>
        /// <param name="querySpecForInit">The query specification for the rewritten query.</param>
        /// <param name="targetRangeToContinuationMap">Map from partition to it's corresponding continuation token.</param>
        /// <param name="deferFirstPage">Whether or not we should defer the fetch of the first page from each partition.</param>
        /// <param name="filter">The filter to inject in the predicate.</param>
        /// <param name="filterCallback">The callback used to filter each partition.</param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>A task to await on.</returns>
        protected async Task InitializeAsync(
            string collectionRid,
            IReadOnlyList <PartitionKeyRange> partitionKeyRanges,
            int initialPageSize,
            SqlQuerySpec querySpecForInit,
            Dictionary <string, string> targetRangeToContinuationMap,
            bool deferFirstPage,
            string filter,
            Func <DocumentProducerTree, Task> filterCallback,
            CancellationToken token)
        {
            CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

            INameValueCollection requestHeaders = await this.CreateCommonHeadersAsync(this.GetFeedOptions(null));

            this.TraceInformation(string.Format(
                                      CultureInfo.InvariantCulture,
                                      "parallel~contextbase.initializeasync, queryspec {0}, maxbuffereditemcount: {1}, target partitionkeyrange count: {2}, maximumconcurrencylevel: {3}, documentproducer initial page size {4}",
                                      JsonConvert.SerializeObject(this.querySpec, DefaultJsonSerializationSettings.Value),
                                      this.actualMaxBufferedItemCount,
                                      partitionKeyRanges.Count,
                                      this.comparableTaskScheduler.MaximumConcurrencyLevel,
                                      initialPageSize));

            List <DocumentProducerTree> documentProducerTrees = new List <DocumentProducerTree>();

            foreach (PartitionKeyRange partitionKeyRange in partitionKeyRanges)
            {
                string initialContinuationToken = (targetRangeToContinuationMap != null && targetRangeToContinuationMap.ContainsKey(partitionKeyRange.Id)) ? targetRangeToContinuationMap[partitionKeyRange.Id] : null;

                DocumentProducerTree documentProducerTree = new DocumentProducerTree(
                    partitionKeyRange,
                    //// Create Document Service Request callback
                    (pkRange, continuationToken, pageSize) =>
                {
                    INameValueCollection headers = requestHeaders.Clone();
                    headers[HttpConstants.HttpHeaders.Continuation] = continuationToken;
                    headers[HttpConstants.HttpHeaders.PageSize]     = pageSize.ToString(CultureInfo.InvariantCulture);
                    return(this.CreateDocumentServiceRequest(
                               headers,
                               querySpecForInit,
                               pkRange,
                               collectionRid));
                },
                    this.ExecuteRequestLazyAsync,
                    //// Retry policy callback
                    () => new NonRetriableInvalidPartitionExceptionRetryPolicy(collectionCache, this.Client.ResetSessionTokenRetryPolicy.GetRequestPolicy()),
                    this.OnDocumentProducerTreeCompleteFetching,
                    this.documentProducerForest.Comparer as IComparer <DocumentProducerTree>,
                    this.equalityComparer,
                    this.Client,
                    deferFirstPage,
                    collectionRid,
                    initialPageSize,
                    initialContinuationToken);

                documentProducerTree.Filter = filter;

                // Prefetch if necessary, and populate consume queue.
                if (this.CanPrefetch)
                {
                    this.TryScheduleFetch(documentProducerTree);
                }

                documentProducerTrees.Add(documentProducerTree);
            }

            // Using loop fisson so that we can load the document producers in parallel
            foreach (DocumentProducerTree documentProducerTree in documentProducerTrees)
            {
                if (!deferFirstPage)
                {
                    await documentProducerTree.MoveNextIfNotSplitAsync(token);
                }

                if (filterCallback != null)
                {
                    await filterCallback(documentProducerTree);
                }

                if (documentProducerTree.HasMoreResults)
                {
                    this.documentProducerForest.Enqueue(documentProducerTree);
                }
            }
        }
コード例 #4
0
        protected async Task RepairContextAsync(
            string collectionRid,
            int currentDocumentProducerIndex,
            Func <DocumentProducer <T>, int> taskPriorityFunc,
            IReadOnlyList <PartitionKeyRange> replacementRanges,
            SqlQuerySpec querySpecForRepair,
            Action callback = null)
        {
            CollectionCache collectionCache = await this.Client.GetCollectionCacheAsync();

            INameValueCollection requestHeaders = await this.CreateCommonHeadersAsync(this.GetFeedOptions(null));

            this.DocumentProducers.Capacity = this.DocumentProducers.Count + replacementRanges.Count - 1;
            DocumentProducer <T> replacedDocumentProducer = this.DocumentProducers[currentDocumentProducerIndex];

            DefaultTrace.TraceInformation(string.Format(
                                              CultureInfo.InvariantCulture,
                                              "{0}, CorrelatedActivityId: {5} | Parallel~ContextBase.RepairContextAsync, MaxBufferedItemCount: {1}, Replacement PartitionKeyRange Count: {2}, MaximumConcurrencyLevel: {3}, DocumentProducer Initial Page Size {4}",
                                              DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                                              this.actualMaxBufferedItemCount,
                                              replacementRanges.Count,
                                              this.TaskScheduler.MaximumConcurrencyLevel,
                                              replacedDocumentProducer.PageSize,
                                              this.CorrelatedActivityId));

            int index = currentDocumentProducerIndex + 1;

            foreach (PartitionKeyRange range in replacementRanges)
            {
                this.DocumentProducers.Insert(
                    index++,
                    new DocumentProducer <T>(
                        this.TaskScheduler,
                        (continuationToken, pageSize) =>
                {
                    INameValueCollection headers = requestHeaders.Clone();
                    headers[HttpConstants.HttpHeaders.Continuation] = continuationToken;
                    headers[HttpConstants.HttpHeaders.PageSize]     = pageSize.ToString(CultureInfo.InvariantCulture);
                    return(this.CreateDocumentServiceRequest(
                               headers,
                               querySpecForRepair,
                               range,
                               collectionRid));
                },
                        range,
                        taskPriorityFunc,
                        this.ExecuteRequestAsync <T>,
                        () => new NonRetriableInvalidPartitionExceptionRetryPolicy(collectionCache, this.Client.RetryPolicy.GetRequestPolicy()),
                        this.OnDocumentProducerCompleteFetching,
                        this.CorrelatedActivityId,
                        replacedDocumentProducer.PageSize,
                        replacedDocumentProducer.CurrentBackendContinuationToken));
            }

            this.DocumentProducers.RemoveAt(currentDocumentProducerIndex);

            if (callback != null)
            {
                callback();
            }

            if (this.ShouldPrefetch)
            {
                for (int i = 0; i < replacementRanges.Count; i++)
                {
                    this.DocumentProducers[i + currentDocumentProducerIndex].TryScheduleFetch();
                }
            }

            if (this.CurrentContinuationTokens.Remove(replacedDocumentProducer))
            {
                for (int i = 0; i < replacementRanges.Count; ++i)
                {
                    this.CurrentContinuationTokens[this.DocumentProducers[currentDocumentProducerIndex + i]] = replacedDocumentProducer.CurrentBackendContinuationToken;
                }
            }
        }