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;
 }
示例#3
0
 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)))
 {
 }
示例#4
0
 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);