public override async Task <QueryResponseCore> DrainAsync(
                int maxElements,
                CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Note-2016-10-25-felixfan: Given what we support now, we should expect to return only 1 document.
                // Note-2019-07-11-brchon: We can return empty pages until all the documents are drained,
                // but then we will have to design a continuation token.

                double requestCharge       = 0;
                long   responseLengthBytes = 0;
                List <QueryPageDiagnostics> diagnosticsPages = new List <QueryPageDiagnostics>();

                while (!this.Source.IsDone)
                {
                    QueryResponseCore sourceResponse = await this.Source.DrainAsync(int.MaxValue, cancellationToken);

                    if (!sourceResponse.IsSuccess)
                    {
                        return(sourceResponse);
                    }

                    requestCharge       += sourceResponse.RequestCharge;
                    responseLengthBytes += sourceResponse.ResponseLengthBytes;
                    if (sourceResponse.Diagnostics != null)
                    {
                        diagnosticsPages.AddRange(sourceResponse.Diagnostics);
                    }

                    foreach (CosmosElement element in sourceResponse.CosmosElements)
                    {
                        RewrittenAggregateProjections rewrittenAggregateProjections = new RewrittenAggregateProjections(
                            this.isValueAggregateQuery,
                            element);
                        this.singleGroupAggregator.AddValues(rewrittenAggregateProjections.Payload);
                    }
                }

                List <CosmosElement> finalResult       = new List <CosmosElement>();
                CosmosElement        aggregationResult = this.singleGroupAggregator.GetResult();

                if (aggregationResult != null)
                {
                    finalResult.Add(aggregationResult);
                }

                return(QueryResponseCore.CreateSuccess(
                           result: finalResult,
                           continuationToken: null,
                           activityId: null,
                           disallowContinuationTokenMessage: null,
                           requestCharge: requestCharge,
                           diagnostics: diagnosticsPages,
                           responseLengthBytes: responseLengthBytes));
            }
            public override async Task <QueryResponseCore> DrainAsync(
                int maxElements,
                CancellationToken cancellationToken)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // Draining aggregates is broken down into two stages
                QueryResponseCore response;

                if (!this.Source.IsDone)
                {
                    // Stage 1:
                    // Drain the aggregates fully from all continuations and all partitions
                    // And return empty pages in the meantime.
                    QueryResponseCore sourceResponse = await this.Source.DrainAsync(int.MaxValue, cancellationToken);

                    if (!sourceResponse.IsSuccess)
                    {
                        return(sourceResponse);
                    }

                    foreach (CosmosElement element in sourceResponse.CosmosElements)
                    {
                        RewrittenAggregateProjections rewrittenAggregateProjections = new RewrittenAggregateProjections(
                            this.isValueAggregateQuery,
                            element);
                        this.singleGroupAggregator.AddValues(rewrittenAggregateProjections.Payload);
                    }

                    if (this.Source.IsDone)
                    {
                        response = this.GetFinalResponse();
                    }
                    else
                    {
                        response = this.GetEmptyPage(sourceResponse);
                    }
                }
                else
                {
                    // Stage 2:
                    // Return the final page after draining.
                    response = this.GetFinalResponse();
                }

                return(response);
            }
コード例 #3
0
        /// <summary>
        /// Drains at most 'maxElements' documents from the AggregateDocumentQueryExecutionComponent.
        /// </summary>
        /// <param name="maxElements">This value is ignored, since the aggregates are aggregated for you.</param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>The aggregate result after all the continuations have been followed.</returns>
        /// <remarks>
        /// Note that this functions follows all continuations meaning that it won't return until all continuations are drained.
        /// This means that if you have a long running query this function will take a very long time to return.
        /// </remarks>
        public override async Task <QueryResponse> DrainAsync(int maxElements, CancellationToken token)
        {
            // Note-2016-10-25-felixfan: Given what we support now, we should expect to return only 1 document.
            // Note-2019-07-11-brchon: We can return empty pages until all the documents are drained,
            // but then we will have to design a continuation token.

            double     requestCharge       = 0;
            long       responseLengthBytes = 0;
            List <Uri> replicaUris         = new List <Uri>();
            ClientSideRequestStatistics requestStatistics       = new ClientSideRequestStatistics();
            PartitionedQueryMetrics     partitionedQueryMetrics = new PartitionedQueryMetrics();
            ResourceType resourceType = ResourceType.Document;
            string       containerRid = null;

            while (!this.IsDone)
            {
                QueryResponse result = await base.DrainAsync(int.MaxValue, token);

                if (!result.IsSuccessStatusCode)
                {
                    return(result);
                }

                containerRid         = result.QueryHeaders.ContainerRid;
                resourceType         = result.QueryHeaders.ResourceType;
                requestCharge       += result.Headers.RequestCharge;
                responseLengthBytes += result.ResponseLengthBytes;
                // DEVNOTE: Add when query metrics is supported
                // partitionedQueryMetrics += new PartitionedQueryMetrics(results.QueryMetrics);
                if (result.RequestStatistics != null)
                {
                    replicaUris.AddRange(result.RequestStatistics.ContactedReplicas);
                }

                foreach (CosmosElement element in result.CosmosElements)
                {
                    RewrittenAggregateProjections rewrittenAggregateProjections = new RewrittenAggregateProjections(
                        this.isValueAggregateQuery,
                        element);
                    this.singleGroupAggregator.AddValues(rewrittenAggregateProjections.Payload);
                }
            }

            List <CosmosElement> finalResult       = new List <CosmosElement>();
            CosmosElement        aggregationResult = this.singleGroupAggregator.GetResult();

            if (aggregationResult != null)
            {
                finalResult.Add(aggregationResult);
            }

            // The replicaUris may have duplicates.
            requestStatistics.ContactedReplicas.AddRange(replicaUris);

            return(QueryResponse.CreateSuccess(
                       result: finalResult,
                       count: finalResult.Count,
                       responseLengthBytes: responseLengthBytes,
                       responseHeaders: new CosmosQueryResponseMessageHeaders(
                           continauationToken: null,
                           disallowContinuationTokenMessage: null,
                           resourceType: resourceType,
                           containerRid: containerRid)
            {
                RequestCharge = requestCharge
            },
                       queryMetrics: this.GetQueryMetrics()));
        }