private ChangeFeedEstimatorIterator( string processorName, ContainerInternal monitoredContainer, ContainerInternal leaseContainer, ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions, Func <string, string, bool, FeedIterator> monitoredContainerFeedCreator) { this.processorName = processorName ?? throw new ArgumentNullException(nameof(processorName)); this.monitoredContainer = monitoredContainer ?? throw new ArgumentNullException(nameof(monitoredContainer)); this.leaseContainer = leaseContainer ?? throw new ArgumentNullException(nameof(leaseContainer)); this.changeFeedEstimatorRequestOptions = changeFeedEstimatorRequestOptions ?? new ChangeFeedEstimatorRequestOptions(); if (this.changeFeedEstimatorRequestOptions.MaxItemCount.HasValue && this.changeFeedEstimatorRequestOptions.MaxItemCount.Value <= 0) { throw new ArgumentOutOfRangeException($"{nameof(this.changeFeedEstimatorRequestOptions.MaxItemCount)} value should be a positive integer."); } this.lazyLeaseDocuments = new AsyncLazy <TryCatch <IReadOnlyList <DocumentServiceLease> > >(valueFactory: (innerCancellationToken) => { return(this.TryInitializeLeaseDocumentsAsync(innerCancellationToken)); }); this.hasMoreResults = true; this.monitoredContainerFeedCreator = monitoredContainerFeedCreator; }
/// <summary> /// For testing purposes /// </summary> internal ChangeFeedEstimatorIterator( ContainerInternal monitoredContainer, ContainerInternal leaseContainer, DocumentServiceLeaseContainer documentServiceLeaseContainer, Func <string, string, bool, FeedIterator> monitoredContainerFeedCreator, ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions) : this( processorName : string.Empty, monitoredContainer : monitoredContainer, leaseContainer : leaseContainer, changeFeedEstimatorRequestOptions : changeFeedEstimatorRequestOptions, monitoredContainerFeedCreator : monitoredContainerFeedCreator) { this.documentServiceLeaseContainer = documentServiceLeaseContainer; }
public ChangeFeedEstimatorIterator( string processorName, ContainerInternal monitoredContainer, ContainerInternal leaseContainer, ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions) : this( processorName, monitoredContainer, leaseContainer, changeFeedEstimatorRequestOptions, (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) => ResultSetIteratorUtils.BuildResultSetIterator( partitionKeyRangeId : partitionKeyRangeId, continuationToken : continuationToken, maxItemCount : 1, container : monitoredContainer, startTime : null, startFromBeginning : string.IsNullOrEmpty(continuationToken))) { }
public ChangeFeedEstimatorIterator( string processorName, ContainerInternal monitoredContainer, ContainerInternal leaseContainer, ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions) : this( processorName, monitoredContainer, leaseContainer, changeFeedEstimatorRequestOptions, (DocumentServiceLease lease, string continuationToken, bool startFromBeginning) => ChangeFeedPartitionKeyResultSetIteratorCore.Create( lease : lease, continuationToken : continuationToken, maxItemCount : 1, container : monitoredContainer, startTime : null, startFromBeginning : string.IsNullOrEmpty(continuationToken))) { }
private async Task ShouldReturnAllLeasesInOnePage(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions) { List <string> ranges = new List <string>() { "0", "1" }; List <DocumentServiceLeaseCore> leases = ranges.Select(pkRangeId => new DocumentServiceLeaseCore() { LeaseToken = pkRangeId }).ToList(); Mock <FeedIterator> mockIterator = new Mock <FeedIterator>(); mockIterator.Setup(i => i.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(GetResponse(HttpStatusCode.NotModified, "0:1")); Mock <DocumentServiceLeaseContainer> mockContainer = new Mock <DocumentServiceLeaseContainer>(); mockContainer.Setup(c => c.GetAllLeasesAsync()).ReturnsAsync(leases); Func <string, string, bool, FeedIterator> feedCreator = (string partitionKeyRangeId, string continuationToken, bool startFromBeginning) => { return(mockIterator.Object); }; ChangeFeedEstimatorIterator remainingWorkEstimator = new ChangeFeedEstimatorIterator( Mock.Of <ContainerInternal>(), Mock.Of <ContainerInternal>(), mockContainer.Object, feedCreator, changeFeedEstimatorRequestOptions); FeedResponse <ChangeFeedProcessorState> response = await remainingWorkEstimator.ReadNextAsync(default(CancellationToken)); Assert.IsFalse(remainingWorkEstimator.HasMoreResults); Assert.AreEqual(ranges.Count, response.Count); }
/// <summary> /// Gets the estimation per lease in the lease container. /// </summary> /// <param name="changeFeedEstimatorRequestOptions">(Optional) Customize the estimation iterator.</param> /// <returns>An iterator that yields an estimation of pending work in amount of transactions per distributed lease token.</returns> /// <remarks> /// The estimation over the Change Feed identifies volumes of transactions. If operations in the container are performed through stored procedures, transactional batch or bulk, a group of operations may share the same <see href="https://docs.microsoft.com/azure/cosmos-db/stored-procedures-triggers-udfs#transactions">transaction scope</see> and represented by a single transaction. /// In those cases, the estimation might not exactly represent number of items, but it is still valid to understand if the pending volume is increasing, decreasing, or on a steady state. /// </remarks> public abstract FeedIterator <ChangeFeedProcessorState> GetCurrentStateIterator(ChangeFeedEstimatorRequestOptions changeFeedEstimatorRequestOptions = null);