public async Task ConcurrentMoveNextTryScheduleTestAsync()
        {
            int    seed     = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
            Random rand     = new Random(seed);
            int    maxValue = 100;
            int    trials   = 1000;
            int    maxTicks = 100;

            IEnumerable <int>          expectedValues = Enumerable.Range(1, maxValue);
            IDocumentClientRetryPolicy retryPolicy    = new MockRetryPolicy(rand);
            ComparableTaskScheduler    scheduler      = new ComparableTaskScheduler(1);

            for (int trial = 0; trial < trials; ++trial)
            {
                DocumentProducer <int> producer = new DocumentProducer <int>(
                    scheduler,
                    (continuation, pageSize) => DocumentServiceRequest.Create(
                        OperationType.Query,
                        "/dbs/db/colls/coll",
                        ResourceType.Document,
                        new MemoryStream(Encoding.UTF8.GetBytes(continuation)),
                        AuthorizationTokenType.PrimaryMasterKey,
                        new StringKeyValueCollection
                {
                    { HttpConstants.HttpHeaders.Continuation, continuation }
                }),
                    new PartitionKeyRange {
                    Id = "test", MinInclusive = "", MaxExclusive = "ff"
                },
                    p => 0,
                    (request, token) =>
                {
                    if (rand.Next(4) == 0)
                    {
                        throw new Exception();
                    }

                    if (rand.Next(10) == 0)
                    {
                        return(Task.FromResult(new FeedResponse <int>(new int[] { }, 0, request.Headers)));
                    }

                    using (StreamReader reader = new StreamReader(request.Body))
                    {
                        int value = int.Parse(reader.ReadToEnd()) + 1;
                        INameValueCollection headers = new StringKeyValueCollection
                        {
                            { HttpConstants.HttpHeaders.Continuation, value >= maxValue? null : value.ToString(CultureInfo.InvariantCulture) }
                        };
                        return(Task.FromResult(new FeedResponse <int>(new int[] { value }, 1, headers)));
                    }
                },
                    () => retryPolicy,
                    (produer, size, ru, queryMetrics, token, length) => { },
                    Guid.NewGuid(),
                    1000,
                    "0");

                Timer timer = new Timer(
                    (state) => producer.TryScheduleFetch(TimeSpan.FromTicks(rand.Next(maxTicks))),
                    null,
                    TimeSpan.FromTicks(rand.Next(maxTicks)),
                    TimeSpan.FromTicks(rand.Next(maxTicks)));

                List <int> actualValues             = new List <int>();
                CancellationTokenSource tokenSource = new CancellationTokenSource(5000);
                while (await producer.MoveNextAsync(tokenSource.Token))
                {
                    actualValues.Add(producer.Current);
                }

                Assert.AreEqual(
                    string.Join(", ", expectedValues),
                    string.Join(", ", actualValues),
                    string.Format(CultureInfo.InvariantCulture, "seed: {0}", seed));
            }
        }
示例#2
0
        private void OnDocumentProducerCompleteFetching(
            DocumentProducer <T> producer,
            int size,
            double resourceUnitUsage,
            QueryMetrics queryMetrics,
            long responseLengthBytes,
            CancellationToken token)
        {
            // Update charge and states
            this.chargeTracker.AddCharge(resourceUnitUsage);
            Interlocked.Add(ref this.totalBufferedItems, size);
            Interlocked.Increment(ref this.totalRequestRoundTrips);
            this.IncrementResponseLengthBytes(responseLengthBytes);
            this.partitionedQueryMetrics.Add(Tuple.Create(producer.TargetRange.Id, queryMetrics));

            //Check to see if we can buffer more item
            long countToAdd = size - this.FreeItemSpace;

            if (countToAdd > 0 &&
                this.actualMaxBufferedItemCount < MaxixmumDynamicMaxBufferedItemCountValue - countToAdd)
            {
                DefaultTrace.TraceVerbose(string.Format(
                                              CultureInfo.InvariantCulture,
                                              "{0}, CorrelatedActivityId: {4} | Id: {1}, increasing MaxBufferedItemCount {2} by {3}.",
                                              DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                                              producer.TargetRange.Id,
                                              this.actualMaxBufferedItemCount,
                                              countToAdd,
                                              this.CorrelatedActivityId));

                countToAdd += this.actualMaxBufferedItemCount;
            }

            // Adjust max DoP if necessary
            this.AdjustTaskSchedulerMaximumConcurrencyLevel();

            // Fetch again if necessary
            if (!producer.FetchedAll)
            {
                if (producer.PageSize < this.actualMaxPageSize)
                {
                    producer.PageSize = Math.Min((long)(producer.PageSize * DynamicPageSizeAdjustmentFactor), this.actualMaxPageSize);

                    Debug.Assert(producer.PageSize >= 0 && producer.PageSize <= int.MaxValue, string.Format("producer.PageSize is invalid at {0}", producer.PageSize));
                }

                if (this.ShouldPrefetch &&
                    this.FreeItemSpace - producer.NormalizedPageSize > 0)
                {
                    producer.TryScheduleFetch();
                }
            }

            DefaultTrace.TraceVerbose(string.Format(
                                          CultureInfo.InvariantCulture,
                                          "{0}, CorrelatedActivityId: {5} | Id: {1}, size: {2}, resourceUnitUsage: {3}, taskScheduler.CurrentRunningTaskCount: {4}",
                                          DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                                          producer.TargetRange.Id,
                                          size,
                                          resourceUnitUsage,
                                          this.TaskScheduler.CurrentRunningTaskCount,
                                          this.CorrelatedActivityId));
        }