Ejemplo n.º 1
0
 private QueryIterator(
     CosmosQueryContext cosmosQueryContext,
     CosmosQueryExecutionContext cosmosQueryExecutionContext,
     CosmosSerializationFormatOptions cosmosSerializationFormatOptions)
 {
     this.cosmosQueryContext               = cosmosQueryContext ?? throw new ArgumentNullException(nameof(cosmosQueryContext));
     this.cosmosQueryExecutionContext      = cosmosQueryExecutionContext ?? throw new ArgumentNullException(nameof(cosmosQueryExecutionContext));
     this.cosmosSerializationFormatOptions = cosmosSerializationFormatOptions;
 }
        public override async Task <QueryResponse> ExecuteNextAsync(CancellationToken token)
        {
            if (this.innerExecutionContext == null)
            {
                this.innerExecutionContext = await this.CreateItemQueryExecutionContextAsync(token);
            }

            QueryResponse response = await this.innerExecutionContext.ExecuteNextAsync(token);

            response.CosmosSerializationOptions = this.cosmosQueryContext.QueryRequestOptions.CosmosSerializationOptions;

            return(response);
        }
 private QueryIterator(
     CosmosQueryContextCore cosmosQueryContext,
     CosmosQueryExecutionContext cosmosQueryExecutionContext,
     CosmosSerializationFormatOptions cosmosSerializationFormatOptions,
     RequestOptions requestOptions,
     CosmosClientContext clientContext)
 {
     this.cosmosQueryContext               = cosmosQueryContext ?? throw new ArgumentNullException(nameof(cosmosQueryContext));
     this.cosmosQueryExecutionContext      = cosmosQueryExecutionContext ?? throw new ArgumentNullException(nameof(cosmosQueryExecutionContext));
     this.cosmosSerializationFormatOptions = cosmosSerializationFormatOptions;
     this.requestOptions = requestOptions;
     this.clientContext  = clientContext ?? throw new ArgumentNullException(nameof(clientContext));
 }
        /// <summary>
        /// This is a helper function to catch any remaining exceptions that should not be thrown.
        /// TODO: Remove all throws that are not argument exceptions
        /// </summary>
        private async Task <ResponseMessage> ExecuteNextHelperAsync(CancellationToken cancellationToken)
        {
            bool          isFirstExecute = false;
            QueryResponse response       = null;

            while (true)
            {
                // The retry policy handles the scenario when the name cache is stale. If the cache is stale the entire
                // execute context has incorrect values and should be recreated. This should only be done for the first
                // execution. If results have already been pulled an error should be returned to the user since it's
                // not possible to combine query results from multiple containers.
                if (this.innerExecutionContext == null)
                {
                    this.innerExecutionContext = await this.CreateItemQueryExecutionContextAsync(cancellationToken);

                    isFirstExecute = true;
                }

                response = await this.innerExecutionContext.ExecuteNextAsync(cancellationToken);

                response.CosmosSerializationOptions = this.cosmosQueryContext.QueryRequestOptions.CosmosSerializationOptions;

                if (response.IsSuccessStatusCode)
                {
                    break;
                }

                if (isFirstExecute && response.StatusCode == HttpStatusCode.Gone && response.Headers.SubStatusCode == SubStatusCodes.NameCacheIsStale)
                {
                    await this.ForceRefreshCollectionCacheAsync(cancellationToken);

                    this.innerExecutionContext = await this.CreateItemQueryExecutionContextAsync(cancellationToken);

                    isFirstExecute = false;
                }
                else
                {
                    break;
                }
            }

            if (response?.queryMetrics != null && response?.queryMetrics.Count > 0)
            {
                response.Diagnostics = new QueryOperationStatistics(response.queryMetrics);
            }

            return(response);
        }
        public override async Task <QueryResponseCore> ExecuteNextAsync(CancellationToken cancellationToken)
        {
            if (this.responseMessageException != null)
            {
                return(this.responseMessageException.Value);
            }

            if (this.exception != null)
            {
                throw this.exception;
            }

            try
            {
                bool isFirstExecute = false;
                QueryResponseCore response;
                while (true)
                {
                    // The retry policy handles the scenario when the name cache is stale. If the cache is stale the entire
                    // execute context has incorrect values and should be recreated. This should only be done for the first
                    // execution. If results have already been pulled an error should be returned to the user since it's
                    // not possible to combine query results from multiple containers.
                    if (this.innerExecutionContext == null)
                    {
                        this.innerExecutionContext = await this.CreateItemQueryExecutionContextAsync(cancellationToken);

                        isFirstExecute = true;
                    }

                    response = await this.innerExecutionContext.ExecuteNextAsync(cancellationToken);

                    if (response.IsSuccess)
                    {
                        break;
                    }

                    if (isFirstExecute && response.StatusCode == HttpStatusCode.Gone && response.SubStatusCode == Documents.SubStatusCodes.NameCacheIsStale)
                    {
                        await this.CosmosQueryContext.QueryClient.ForceRefreshCollectionCacheAsync(
                            this.CosmosQueryContext.ResourceLink.OriginalString,
                            cancellationToken);

                        this.innerExecutionContext = await this.CreateItemQueryExecutionContextAsync(cancellationToken);

                        isFirstExecute = false;
                    }
                    else
                    {
                        break;
                    }
                }

                if (!response.IsSuccess)
                {
                    this.responseMessageException = response;
                }

                return(response);
            }
            catch (Exception e)
            {
                this.exception = e;
                this.Dispose();
                throw;
            }
        }
        public override async Task <QueryResponseCore> ExecuteNextAsync(CancellationToken cancellationToken)
        {
            if (this.responseMessageException != null)
            {
                return(this.responseMessageException.Value);
            }

            if (this.exception != null)
            {
                throw this.exception;
            }

            try
            {
                bool isFirstExecute = false;
                QueryResponseCore response;
                while (true)
                {
                    // The retry policy handles the scenario when the name cache is stale. If the cache is stale the entire
                    // execute context has incorrect values and should be recreated. This should only be done for the first
                    // execution. If results have already been pulled an error should be returned to the user since it's
                    // not possible to combine query results from multiple containers.
                    if (this.innerExecutionContext == null)
                    {
                        TryCatch <CosmosQueryExecutionContext> tryCreateItemQueryExecutionContext = await this.TryCreateItemQueryExecutionContextAsync(cancellationToken);

                        if (!tryCreateItemQueryExecutionContext.Succeeded)
                        {
                            // Failed to create pipeline (due to a bad request).
                            return(QueryResponseCore.CreateFailure(
                                       HttpStatusCode.BadRequest,
                                       subStatusCodes: null,
                                       errorMessage: tryCreateItemQueryExecutionContext.Exception.ToString(),
                                       requestCharge: 0,
                                       activityId: this.CosmosQueryContext.CorrelatedActivityId.ToString(),
                                       diagnostics: QueryResponseCore.EmptyDiagnostics));
                        }

                        this.innerExecutionContext = tryCreateItemQueryExecutionContext.Result;
                        isFirstExecute             = true;
                    }

                    response = await this.innerExecutionContext.ExecuteNextAsync(cancellationToken);

                    if (response.IsSuccess)
                    {
                        break;
                    }

                    if (isFirstExecute &&
                        (response.StatusCode == HttpStatusCode.Gone) &&
                        (response.SubStatusCode == Documents.SubStatusCodes.NameCacheIsStale))
                    {
                        await this.CosmosQueryContext.QueryClient.ForceRefreshCollectionCacheAsync(
                            this.CosmosQueryContext.ResourceLink.OriginalString,
                            cancellationToken);

                        TryCatch <CosmosQueryExecutionContext> tryCreateItemQueryExecutionContext = await this.TryCreateItemQueryExecutionContextAsync(cancellationToken);

                        if (!tryCreateItemQueryExecutionContext.Succeeded)
                        {
                            // Failed to create pipeline (due to a bad request).
                            return(QueryResponseCore.CreateFailure(
                                       HttpStatusCode.BadRequest,
                                       subStatusCodes: null,
                                       errorMessage: tryCreateItemQueryExecutionContext.Exception.ToString(),
                                       requestCharge: 0,
                                       activityId: this.CosmosQueryContext.CorrelatedActivityId.ToString(),
                                       diagnostics: QueryResponseCore.EmptyDiagnostics));
                        }

                        this.innerExecutionContext = tryCreateItemQueryExecutionContext.Result;
                        isFirstExecute             = false;
                    }
                    else
                    {
                        break;
                    }
                }

                if (!response.IsSuccess)
                {
                    this.responseMessageException = response;
                }

                return(response);
            }
            catch (Exception e)
            {
                this.exception = e;
                this.Dispose();
                throw;
            }
        }