示例#1
0
        private async Task <ResponseMessage> ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnostics,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            Stream        stream    = null;
            OperationType operation = OperationType.ReadFeed;

            if (this.querySpec != null)
            {
                stream    = this.clientContext.SerializerCore.ToStreamSqlQuerySpec(this.querySpec, this.resourceType);
                operation = OperationType.Query;
            }

            ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync(
                resourceUri : this.containerCore.LinkUri,
                resourceType : this.resourceType,
                operationType : operation,
                requestOptions : this.queryRequestOptions,
                cosmosContainerCore : this.containerCore,
                partitionKey : this.queryRequestOptions?.PartitionKey,
                streamPayload : stream,
                requestEnricher : request =>
            {
                FeedRangeVisitor feedRangeVisitor = new FeedRangeVisitor(request);
                this.FeedRangeInternal.Accept(feedRangeVisitor);
                this.FeedRangeContinuation.Accept(feedRangeVisitor, QueryRequestOptions.FillContinuationToken);
                if (this.querySpec != null)
                {
                    request.Headers.Add(HttpConstants.HttpHeaders.ContentType, MediaTypes.QueryJson);
                    request.Headers.Add(HttpConstants.HttpHeaders.IsQuery, bool.TrueString);
                }
            },
                diagnosticsContext : diagnostics,
                cancellationToken : cancellationToken);

            ShouldRetryResult shouldRetryOnSplit = await this.FeedRangeContinuation.HandleSplitAsync(this.containerCore, responseMessage, cancellationToken);

            if (shouldRetryOnSplit.ShouldRetry)
            {
                return(await this.ReadNextInternalAsync(diagnostics, cancellationToken));
            }

            if (responseMessage.Content != null)
            {
                await CosmosElementSerializer.RewriteStreamAsTextAsync(responseMessage, this.queryRequestOptions);
            }

            if (responseMessage.IsSuccessStatusCode)
            {
                this.FeedRangeContinuation.ReplaceContinuation(responseMessage.Headers.ContinuationToken);
                this.hasMoreResultsInternal = !this.FeedRangeContinuation.IsDone;
                return(FeedRangeResponse.CreateSuccess(responseMessage, this.FeedRangeContinuation));
            }
            else
            {
                this.hasMoreResultsInternal = false;
                return(FeedRangeResponse.CreateFailure(responseMessage));
            }
        }
        private async Task<ResponseMessage> ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnostics,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync(
               resourceUri: this.containerCore.LinkUri,
               resourceType: ResourceType.Document,
               operationType: OperationType.ReadFeed,
               requestOptions: this.queryRequestOptions,
               cosmosContainerCore: this.containerCore,
               partitionKey: this.queryRequestOptions?.PartitionKey,
               streamPayload: null,
               requestEnricher: request =>
               {
                   FeedRangeVisitor feedRangeVisitor = new FeedRangeVisitor(request);
                   this.FeedRangeInternal.Accept(feedRangeVisitor);
                   this.FeedRangeContinuation.Accept(feedRangeVisitor, QueryRequestOptions.FillContinuationToken);
               },
               diagnosticsContext: diagnostics,
               cancellationToken: cancellationToken);

            ShouldRetryResult shouldRetryOnSplit = await this.FeedRangeContinuation.HandleSplitAsync(this.containerCore, responseMessage, cancellationToken);
            if (shouldRetryOnSplit.ShouldRetry)
            {
                return await this.ReadNextInternalAsync(diagnostics, cancellationToken);
            }

            if (responseMessage.Content != null)
            {
                await CosmosElementSerializer.RewriteStreamAsTextAsync(responseMessage, this.queryRequestOptions);
            }

            if (responseMessage.IsSuccessStatusCode)
            {
                this.FeedRangeContinuation.ReplaceContinuation(responseMessage.Headers.ContinuationToken);
                this.hasMoreResultsInternal = !this.FeedRangeContinuation.IsDone;
                return FeedRangeResponse.CreateSuccess(responseMessage, this.FeedRangeContinuation);
            }
            else
            {
                this.hasMoreResultsInternal = false;
                return FeedRangeResponse.CreateFailure(responseMessage);
            }
        }
        private async Task <ResponseMessage> ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnosticsScope,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync(
                resourceUri : this.container.LinkUri,
                resourceType : ResourceType.Document,
                operationType : OperationType.ReadFeed,
                requestOptions : this.changeFeedOptions,
                cosmosContainerCore : this.container,
                requestEnricher : request =>
            {
                FeedRangeVisitor feedRangeVisitor = new FeedRangeVisitor(request);
                this.FeedRangeInternal.Accept(feedRangeVisitor);
                this.FeedRangeContinuation.Accept(feedRangeVisitor, ChangeFeedRequestOptions.FillContinuationToken);
            },
                partitionKey : null,
                streamPayload : null,
                diagnosticsContext : diagnosticsScope,
                cancellationToken : cancellationToken);

            if (await this.ShouldRetryAsync(responseMessage, cancellationToken))
            {
                return(await this.ReadNextInternalAsync(diagnosticsScope, cancellationToken));
            }

            if (responseMessage.IsSuccessStatusCode ||
                responseMessage.StatusCode == HttpStatusCode.NotModified)
            {
                // Change Feed read uses Etag for continuation
                this.FeedRangeContinuation.ReplaceContinuation(responseMessage.Headers.ETag);
                this.hasMoreResults = responseMessage.IsSuccessStatusCode;
                return(FeedRangeResponse.CreateSuccess(
                           responseMessage,
                           this.FeedRangeContinuation));
            }
            else
            {
                this.hasMoreResults = false;
                return(FeedRangeResponse.CreateFailure(responseMessage));
            }
        }
        private async Task <ResponseMessage> ReadNextInternalAsync(
            CosmosDiagnosticsContext diagnostics,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync(
                resourceUri : this.containerCore.LinkUri,
                resourceType : ResourceType.Document,
                operationType : OperationType.ReadFeed,
                requestOptions : this.queryRequestOptions,
                cosmosContainerCore : this.containerCore,
                partitionKey : this.queryRequestOptions?.PartitionKey,
                streamPayload : null,
                requestEnricher : request =>
            {
                FeedRangeVisitor feedRangeVisitor = new FeedRangeVisitor(request);
                this.FeedRangeInternal.Accept(feedRangeVisitor);
                this.FeedRangeContinuation.Accept(feedRangeVisitor, QueryRequestOptions.FillContinuationToken);
            },
                diagnosticsContext : diagnostics,
                cancellationToken : cancellationToken);

            ShouldRetryResult shouldRetryOnSplit = await this.FeedRangeContinuation.HandleSplitAsync(this.containerCore, responseMessage, cancellationToken);

            if (shouldRetryOnSplit.ShouldRetry)
            {
                return(await this.ReadNextInternalAsync(diagnostics, cancellationToken));
            }

            if (responseMessage.Content != null)
            {
                // Rewrite the payload to be in the specified format.
                // If it's already in the correct format, then the following will be a memcpy.
                MemoryStream memoryStream;
                if (responseMessage.Content is MemoryStream responseContentAsMemoryStream)
                {
                    memoryStream = responseContentAsMemoryStream;
                }
                else
                {
                    memoryStream = new MemoryStream();
                    await responseMessage.Content.CopyToAsync(memoryStream);
                }

                ReadOnlyMemory <byte> buffer;
                if (memoryStream.TryGetBuffer(out ArraySegment <byte> segment))
                {
                    buffer = segment.Array.AsMemory().Slice(start: segment.Offset, length: segment.Count);
                }
                else
                {
                    buffer = memoryStream.ToArray();
                }

                IJsonReader jsonReader = JsonReader.Create(buffer);
                IJsonWriter jsonWriter;
                if (this.queryRequestOptions?.CosmosSerializationFormatOptions != null)
                {
                    jsonWriter = this.queryRequestOptions.CosmosSerializationFormatOptions.CreateCustomWriterCallback();
                }
                else
                {
                    jsonWriter = NewtonsoftToCosmosDBWriter.CreateTextWriter();
                }

                jsonWriter.WriteAll(jsonReader);

                ReadOnlyMemory <byte> result = jsonWriter.GetResult();
                MemoryStream          rewrittenMemoryStream;
                if (MemoryMarshal.TryGetArray(result, out ArraySegment <byte> rewrittenSegment))
                {
                    rewrittenMemoryStream = new MemoryStream(rewrittenSegment.Array, index: rewrittenSegment.Offset, count: rewrittenSegment.Count);
                }
                else
                {
                    rewrittenMemoryStream = new MemoryStream(result.ToArray());
                }

                responseMessage.Content = rewrittenMemoryStream;
            }

            if (responseMessage.IsSuccessStatusCode)
            {
                this.FeedRangeContinuation.ReplaceContinuation(responseMessage.Headers.ContinuationToken);
                this.hasMoreResultsInternal = !this.FeedRangeContinuation.IsDone;
                return(FeedRangeResponse.CreateSuccess(responseMessage, this.FeedRangeContinuation));
            }
            else
            {
                this.hasMoreResultsInternal = false;
                return(FeedRangeResponse.CreateFailure(responseMessage));
            }
        }