public void starts_low()
 {
     using (var sut = new DynamicThrottling(100, 10, 3, 5, 1, 8000))
     {
         Assert.IsTrue(10 == sut.AvailableDegreesOfParallelism);
     }
 }
        public void increases_on_completed_work()
        {
            using (var sut = new DynamicThrottling(100, 10, 3, 5, 1, 8000))
            {
                sut.NotifyWorkStarted();
                var startingValue = sut.AvailableDegreesOfParallelism;

                sut.NotifyWorkCompleted();

                Assert.IsTrue(startingValue < sut.AvailableDegreesOfParallelism);
            }
        }
        public void decreases_on_penalize()
        {
            using (var sut = new DynamicThrottling(100, 10, 3, 5, 1, 8000))
            {
                IncreaseDegreesOfParallelism(sut);

                sut.NotifyWorkStarted();
                var startingValue = sut.AvailableDegreesOfParallelism;
                sut.Penalize();

                Assert.IsTrue(startingValue > sut.AvailableDegreesOfParallelism);
            }
        }
        public void penalize_decreases_less_than_completed_with_error()
        {
            using (var sut1 = new DynamicThrottling(100, 10, 3, 5, 1, 8000))
            using (var sut2 = new DynamicThrottling(100, 10, 3, 5, 1, 8000))
            {
                IncreaseDegreesOfParallelism(sut1);
                IncreaseDegreesOfParallelism(sut2);

                sut1.NotifyWorkStarted();
                sut2.NotifyWorkStarted();

                sut1.Penalize();
                sut2.NotifyWorkCompletedWithError();

                Assert.IsTrue(sut1.AvailableDegreesOfParallelism > sut2.AvailableDegreesOfParallelism);
            }
        }
        protected SubscriptionReceiver(ServiceBusSettings settings, string topic, string subscription, bool processInParallel, ISubscriptionReceiverInstrumentation instrumentation, int maxNumberRetry, RetryStrategy backgroundRetryStrategy)
        {
            this.settings = settings;
            this.topic = topic;
            this.subscription = subscription;
            this.processInParallel = processInParallel;
            this.instrumentation = instrumentation;

            var messagingFactory = MessagingFactory.CreateFromConnectionString(this.settings.ConnectionString);
            this.client = messagingFactory.CreateSubscriptionClient(topic, subscription);
            if (this.processInParallel)
            {
                this.client.PrefetchCount = 500;
            }
            else
            {
                this.client.PrefetchCount = 100;
            }

            this.dynamicThrottling =
                new DynamicThrottling(
                    maxDegreeOfParallelism: 10000,
                    minDegreeOfParallelism: 50,
                    penaltyAmount: 3,
                    workFailedPenaltyAmount: 5,
                    workCompletedParallelismGain: 1,
                    intervalForRestoringDegreeOfParallelism: 8000);

            this.retryStrategy = backgroundRetryStrategy;
            this.maxNumberRetry = maxNumberRetry;

            this.receiveRetryPolicy = new RetryPolicy<ServiceBusTransientErrorDetectionStrategy>(backgroundRetryStrategy);
            this.receiveRetryPolicy.Retrying += (s, e) =>
            {
                this.dynamicThrottling.Penalize();
                Trace.TraceWarning(
                    "An error occurred in attempt number {1} to receive a message from subscription {2}: {0}",
                    e.LastException.Message,
                    e.CurrentRetryCount,
                    this.subscription);
            };
        }
 private static void IncreaseDegreesOfParallelism(DynamicThrottling sut)
 {
     for (int i = 0; i < 10; i++)
     {
         // increase degrees to avoid being in the minimum boundary
         sut.NotifyWorkStarted();
         sut.NotifyWorkCompleted();
     }
 }