private async Task <IReadOnlyList <Documents.PartitionKeyRange> > TryGetOverlappingRangesAsync( Routing.PartitionKeyRangeCache partitionKeyRangeCache, string min, string max, bool forceRefresh = false) { IReadOnlyList <Documents.PartitionKeyRange> keyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( this.ContainerRid, new Documents.Routing.Range <string>( min, max, isMaxInclusive: false, isMinInclusive: true), forceRefresh); if (keyRanges.Count == 0) { throw new ArgumentOutOfRangeException("RequestContinuation", $"Token contains invalid range {min}-{max}"); } return(keyRanges); }
private async Task <ResponseMessage> ReadNextInternalAsync( CosmosDiagnosticsContext diagnosticsScope, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); if (this.feedTokenInternal == null) { Routing.PartitionKeyRangeCache partitionKeyRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(); string containerRId = await this.container.GetRIDAsync(cancellationToken); IReadOnlyList <Documents.PartitionKeyRange> partitionKeyRanges = await partitionKeyRangeCache.TryGetOverlappingRangesAsync( containerRId, new Documents.Routing.Range <string>( Documents.Routing.PartitionKeyInternal.MinimumInclusiveEffectivePartitionKey, Documents.Routing.PartitionKeyInternal.MaximumExclusiveEffectivePartitionKey, isMinInclusive: true, isMaxInclusive: false), forceRefresh : true); // ReadAll scenario, initialize with one token for all this.feedTokenInternal = new FeedTokenEPKRange(containerRId, partitionKeyRanges); } Uri resourceUri = this.container.LinkUri; ResponseMessage responseMessage = await this.clientContext.ProcessResourceOperationStreamAsync( resourceUri : resourceUri, resourceType : Documents.ResourceType.Document, operationType : Documents.OperationType.ReadFeed, requestOptions : this.changeFeedOptions, cosmosContainerCore : this.container, requestEnricher : request => { ChangeFeedRequestOptions.FillContinuationToken(request, this.feedTokenInternal.GetContinuation()); this.feedTokenInternal.EnrichRequest(request); }, partitionKey : null, streamPayload : null, diagnosticsScope : diagnosticsScope, cancellationToken : cancellationToken); // Retry in case of splits or other scenarios if (await this.feedTokenInternal.ShouldRetryAsync(this.container, responseMessage, cancellationToken)) { if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } return(await this.ReadNextInternalAsync(diagnosticsScope, cancellationToken)); } if (responseMessage.IsSuccessStatusCode || responseMessage.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation this.feedTokenInternal.UpdateContinuation(responseMessage.Headers.ETag); } this.hasMoreResults = responseMessage.IsSuccessStatusCode; return(responseMessage); }