internal async Task <Tuple <string, ResponseMessage> > ReadNextInternalAsync(ITrace trace, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (trace == null) { throw new ArgumentNullException(nameof(trace)); } if (this.compositeContinuationToken == null) { PartitionKeyRangeCache pkRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(); this.containerRid = await this.container.GetCachedRIDAsync( forceRefresh : false, trace, cancellationToken : cancellationToken); this.compositeContinuationToken = await StandByFeedContinuationToken.CreateAsync( this.containerRid, this.continuationToken, pkRangeCache.TryGetOverlappingRangesAsync); } (CompositeContinuationToken currentRangeToken, string rangeId) = await this.compositeContinuationToken.GetCurrentTokenAsync(); string partitionKeyRangeId = rangeId; this.continuationToken = currentRangeToken.Token; ResponseMessage response = await this.NextResultSetDelegateAsync(this.continuationToken, partitionKeyRangeId, this.maxItemCount, this.changeFeedOptions, trace, cancellationToken); if (await this.ShouldRetryFailureAsync(response, cancellationToken)) { return(await this.ReadNextInternalAsync(trace, cancellationToken)); } if (response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation currentRangeToken.Token = response.Headers.ETag; } return(new Tuple <string, ResponseMessage>(partitionKeyRangeId, response)); }
public static string CreateForRange( string containerRid, string minInclusive, string maxExclusive) { if (string.IsNullOrWhiteSpace(containerRid)) { throw new ArgumentNullException(nameof(containerRid)); } // MinInclusive can be an empty string if (minInclusive == null) { throw new ArgumentNullException(nameof(minInclusive)); } if (string.IsNullOrWhiteSpace(maxExclusive)) { throw new ArgumentNullException(nameof(maxExclusive)); } return(StandByFeedContinuationToken.SerializeTokens(new CompositeContinuationToken[1] { StandByFeedContinuationToken.CreateCompositeContinuationTokenForRange(minInclusive, maxExclusive, null) })); }
internal async Task <(string, ResponseMessage)> ReadNextInternalAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (this.compositeContinuationToken == null) { PartitionKeyRangeCache pkRangeCache = await this.clientContext.DocumentClient.GetPartitionKeyRangeCacheAsync(); this.containerRid = await this.container.GetRIDAsync(cancellationToken); if (this.changeFeedStartFrom is ChangeFeedStartFromContinuation startFromContinuation) { this.compositeContinuationToken = await StandByFeedContinuationToken.CreateAsync( this.containerRid, startFromContinuation.Continuation, pkRangeCache.TryGetOverlappingRangesAsync); (CompositeContinuationToken token, string id) = await this.compositeContinuationToken.GetCurrentTokenAsync(); if (token.Token != null) { this.changeFeedStartFrom = ChangeFeedStartFrom.ContinuationToken(token.Token); } else { this.changeFeedStartFrom = ChangeFeedStartFrom.Beginning(); } } else { this.compositeContinuationToken = await StandByFeedContinuationToken.CreateAsync( this.containerRid, initialStandByFeedContinuationToken : null, pkRangeCache.TryGetOverlappingRangesAsync); } } (CompositeContinuationToken currentRangeToken, string rangeId) = await this.compositeContinuationToken.GetCurrentTokenAsync(); FeedRange feedRange = new FeedRangePartitionKeyRange(rangeId); if (currentRangeToken.Token != null) { this.changeFeedStartFrom = new ChangeFeedStartFromContinuationAndFeedRange(currentRangeToken.Token, (FeedRangeInternal)feedRange); } else { this.changeFeedStartFrom = ChangeFeedStartFrom.Beginning(feedRange); } ResponseMessage response = await this.NextResultSetDelegateAsync(this.changeFeedOptions, cancellationToken); if (await this.ShouldRetryFailureAsync(response, cancellationToken)) { return(await this.ReadNextInternalAsync(cancellationToken)); } if (response.IsSuccessStatusCode || response.StatusCode == HttpStatusCode.NotModified) { // Change Feed read uses Etag for continuation currentRangeToken.Token = response.Headers.ETag; } return(rangeId, response); }