Esempio n. 1
0
        public void TestWarmUpWithColdFactor()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0, 4000, TimeUnit.Milliseconds, 10.0);

            for (int i = 0; i < 8; i++)
            {
                limiter.Acquire();       // #1
            }
            stopwatch.SleepMillis(200);  // #2: to repay for the last Acquire
            stopwatch.SleepMillis(4000); // #3: becomes cold again
            for (int i = 0; i < 8; i++)
            {
                limiter.Acquire();       // // #4
            }
            stopwatch.SleepMillis(200);  // #5: to repay for the last Acquire
            stopwatch.SleepMillis(1000); // #6: still warm! It would take another 3 seconds to go cold
            for (int i = 0; i < 8; i++)
            {
                limiter.Acquire(); // #7
            }

            AssertEvents(stopwatch, "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20", // #1
                         "U0.20",                                                             // #2
                         "U4.00",                                                             // #3
                         "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20",            // #4
                         "U0.20",                                                             // #5
                         "U1.00",                                                             // #6
                         "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20");           // #7
        }
Esempio n. 2
0
        public void TestInfinity_Bursty()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, double.PositiveInfinity);

            limiter.Acquire(int.MaxValue / 4);
            limiter.Acquire(int.MaxValue / 2);
            limiter.Acquire(int.MaxValue);
            AssertEvents(stopwatch, "R0.00", "R0.00", "R0.00"); // no wait, infinite rate!

            limiter.SetRate(2.0);
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            AssertEvents(stopwatch, "R0.00", // First comes the saved-up burst, which defaults to a 1-second burst (2 requests).
                         "R0.00",
                         "R0.00",            // Now comes the free request.
                         "R0.50",            // Now it's 0.5 seconds per request.
                         "R0.50");

            limiter.SetRate(double.PositiveInfinity);
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            AssertEvents(stopwatch, "R0.50", "R0.00", "R0.00"); // we repay the last request (.5sec), then back to +oo
        }
Esempio n. 3
0
        public void TestWarmUp()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 2.0, 4000, TimeUnit.Milliseconds, 3.0);

            for (var i = 0; i < 8; i++)
            {
                limiter.Acquire();       // #1
            }
            stopwatch.SleepMillis(500);  // #2: to repay for the last Acquire
            stopwatch.SleepMillis(4000); // #3: becomes cold again
            for (var i = 0; i < 8; i++)
            {
                limiter.Acquire();       // // #4
            }
            stopwatch.SleepMillis(500);  // #5: to repay for the last Acquire
            stopwatch.SleepMillis(2000); // #6: didn't get cold! It would take another 2 seconds to go cold
            for (var i = 0; i < 8; i++)
            {
                limiter.Acquire();                                                            // #7
            }
            AssertEvents(stopwatch, "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
                         "U0.50",                                                             // #2
                         "U4.00",                                                             // #3
                         "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50",            // #4
                         "U0.50",                                                             // #5
                         "U2.00",                                                             // #6
                         "R0.00, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50");           // #7
        }
Esempio n. 4
0
        public void TestTryAcquire_overflow()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            Assert.IsTrue(limiter.TryAcquire(timeout: 0, unit: TimeUnit.Microseconds));
            stopwatch.SleepMillis(100);
            Assert.IsTrue(limiter.TryAcquire(timeout: long.MaxValue, unit: TimeUnit.Microseconds));
        }
Esempio n. 5
0
        public void TestVerySmallDoubleValues() //throws
        {
            var stopwatch   = new FakeStopwatch();
            var rateLimiter = RateLimiter.Create(stopwatch, Epsilon);

            Assert.IsTrue(rateLimiter.TryAcquire(), "Should Acquire initial permit");
            Assert.IsFalse(rateLimiter.TryAcquire(), "Should not Acquire additional permit");
            stopwatch.SleepMillis(5000);
            Assert.IsFalse(rateLimiter.TryAcquire(), "Should not Acquire additional permit even after sleeping");
        }
Esempio n. 6
0
        public void TestSimple()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            limiter.Acquire(); // R0.00, since it's the first request
            limiter.Acquire(); // R0.20
            limiter.Acquire(); // R0.20
            AssertEvents(stopwatch, "R0.00", "R0.20", "R0.20");
        }
Esempio n. 7
0
        public void TestSimpleAcquireEarliestAvailableIsInPast()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            Assert.AreEqual(0.0, limiter.Acquire(), Epsilon);
            stopwatch.SleepMillis(400);
            Assert.AreEqual(0.0, limiter.Acquire(), Epsilon);
            Assert.AreEqual(0.0, limiter.Acquire(), Epsilon);
            Assert.AreEqual(0.2, limiter.Acquire(), Epsilon);
        }
Esempio n. 8
0
        public void TestSimpleAcquireReturnValues()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            Assert.AreEqual(0.0, limiter.Acquire(), Epsilon); // R0.00
            stopwatch.SleepMillis(200);                       // U0.20, we are ready for the next request...
            Assert.AreEqual(0.0, limiter.Acquire(), Epsilon); // R0.00, ...which is granted immediately
            Assert.AreEqual(0.2, limiter.Acquire(), Epsilon); // R0.20
            AssertEvents(stopwatch, "R0.00", "U0.20", "R0.00", "R0.20");
        }
Esempio n. 9
0
        public void Should_Start_At_Zero()
        {
            // Arrange
            IStopwatch sw = new FakeStopwatch(tickIncrementMilliseconds: 400);

            // Act
            int actualTime = sw.ElapsedTimeMs;

            // Assert
            Assert.Equal(0, actualTime);
        }
Esempio n. 10
0
        public void TestTryAcquire_someWaitAllowed()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            Assert.IsTrue(limiter.TryAcquire(timeout: 0, unit: TimeUnit.Seconds));
            Assert.IsTrue(limiter.TryAcquire(timeout: 200, unit: TimeUnit.Milliseconds));
            Assert.IsFalse(limiter.TryAcquire(timeout: 100, unit: TimeUnit.Milliseconds));
            stopwatch.SleepMillis(100);
            Assert.IsTrue(limiter.TryAcquire(timeout: 100, unit: TimeUnit.Milliseconds));
        }
Esempio n. 11
0
        public void TestSimpleWithWait()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            limiter.Acquire();          // R0.00
            stopwatch.SleepMillis(200); // U0.20, we are ready for the next request...
            limiter.Acquire();          // R0.00, ...which is granted immediately
            limiter.Acquire();          // R0.20
            AssertEvents(stopwatch, "R0.00", "U0.20", "R0.00", "R0.20");
        }
Esempio n. 12
0
        public void TestDoubleMinValueCanAcquireExactlyOnce()
        {
            var stopwatch = new FakeStopwatch();
            var r         = RateLimiter.Create(stopwatch, Epsilon);

            Assert.IsTrue(r.TryAcquire(), "Unable to Acquire initial permit");
            Assert.IsFalse(r.TryAcquire(), "Capable of acquiring an additional permit");
            stopwatch.SleepMillis(int.MaxValue);
            Assert.IsFalse(r.TryAcquire(), "Capable of acquiring an additional permit after sleeping");
            stopwatch.ReadEventsAndClear();
        }
Esempio n. 13
0
        public void TestTryAcquire_negative()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            Assert.IsTrue(limiter.TryAcquire(5, 0, TimeUnit.Seconds));
            stopwatch.SleepMillis(900);
            Assert.IsFalse(limiter.TryAcquire(1, long.MinValue, TimeUnit.Seconds));
            stopwatch.SleepMillis(100);
            Assert.IsTrue(limiter.TryAcquire(1, -1, TimeUnit.Seconds));
        }
Esempio n. 14
0
        private long MeasureTotalTimeMillis(FakeStopwatch stopwatch, RateLimiter rateLimiter, int permits, Random random)
        {
            var startTime = stopwatch.Instant;

            while (permits > 0)
            {
                var nextPermitsToAcquire = Math.Max(1, random.Next(permits));
                permits -= nextPermitsToAcquire;
                rateLimiter.Acquire(nextPermitsToAcquire);
            }
            rateLimiter.Acquire(1); // to repay for any pending debt
            return(TimeUnit.Nanoseconds.ToMillis(stopwatch.Instant - startTime));
        }
Esempio n. 15
0
        public void TestInfinity_WarmUpTimeElapsed()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, double.PositiveInfinity, 10, TimeUnit.Seconds, 3.0);

            stopwatch.Instant += 1000000;
            limiter.SetRate(1.0);
            for (var i = 0; i < 5; i++)
            {
                limiter.Acquire();
            }
            AssertEvents(stopwatch, "R0.00", "R1.00", "R1.00", "R1.00", "R1.00");
        }
Esempio n. 16
0
        public void TestSimpleWeights()
        {
            var stopwatch   = new FakeStopwatch();
            var rateLimiter = RateLimiter.Create(stopwatch, 1.0);

            rateLimiter.Acquire(1); // no wait
            rateLimiter.Acquire(1); // R1.00, to repay previous
            rateLimiter.Acquire(2); // R1.00, to repay previous
            rateLimiter.Acquire(4); // R2.00, to repay previous
            rateLimiter.Acquire(8); // R4.00, to repay previous
            rateLimiter.Acquire(1); // R8.00, to repay previous
            AssertEvents(stopwatch, "R0.00", "R1.00", "R1.00", "R2.00", "R4.00", "R8.00");
        }
Esempio n. 17
0
        public void Should_Reset_Back_To_Zero()
        {
            // Arrange
            IStopwatch sw = new FakeStopwatch(tickIncrementMilliseconds: 400);

            // Act
            sw.Advance();
            sw.Restart();

            // Assert
            Assert.Equal(0, sw.ElapsedTimeMs);
            Assert.Equal(0, sw.ElapsedTimeSeconds);
        }
Esempio n. 18
0
        public void TestBurstyAndUpdate()
        {
            var stopwatch   = new FakeStopwatch();
            var rateLimiter = RateLimiter.Create(stopwatch, 1.0);

            rateLimiter.Acquire(1);   // no wait
            rateLimiter.Acquire(1);   // R1.00, to repay previous

            rateLimiter.SetRate(2.0); // update the rate!

            rateLimiter.Acquire(1);   // R1.00, to repay previous (the previous was under the old rate!)
            rateLimiter.Acquire(2);   // R0.50, to repay previous (now the rate takes effect)
            rateLimiter.Acquire(4);   // R1.00, to repay previous
            rateLimiter.Acquire(1);   // R2.00, to repay previous
            AssertEvents(stopwatch, "R0.00", "R1.00", "R1.00", "R0.50", "R1.00", "R2.00");
        }
Esempio n. 19
0
        public void Should_Advance_Forward()
        {
            // Arrange
            IStopwatch sw = new FakeStopwatch(tickIncrementMilliseconds: 400);

            // Act
            const int times = 3;

            for (int i = times - 1; i >= 0; i--)
            {
                sw.Advance();
            }

            // Assert
            Assert.Equal(1_200, sw.ElapsedTimeMs);
            Assert.Equal(1, sw.ElapsedTimeSeconds);
        }
Esempio n. 20
0
        public void TestInfinity_BustyTimeElapsed()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, double.PositiveInfinity);

            stopwatch.Instant += 1000000;
            limiter.SetRate(2.0);
            for (var i = 0; i < 5; i++)
            {
                limiter.Acquire();
            }
            AssertEvents(stopwatch, "R0.00", // First comes the saved-up burst, which defaults to a 1-second burst (2 requests).
                         "R0.00",
                         "R0.00",            // Now comes the free request.
                         "R0.50",            // Now it's 0.5 seconds per request.
                         "R0.50");
        }
Esempio n. 21
0
        public void TestOneSecondBurst()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0);

            stopwatch.SleepMillis(1000);                     // max capacity reached
            stopwatch.SleepMillis(1000);                     // this makes no difference
            limiter.Acquire(1);                              // R0.00, since it's the first request

            limiter.Acquire(1);                              // R0.00, from capacity
            limiter.Acquire(3);                              // R0.00, from capacity
            limiter.Acquire(1);                              // R0.00, concluding a burst of 5 permits

            limiter.Acquire();                               // R0.20, capacity exhausted
            AssertEvents(stopwatch, "U1.00", "U1.00",
                         "R0.00", "R0.00", "R0.00", "R0.00", // first request and burst
                         "R0.20");
        }
Esempio n. 22
0
        public void TestWarmUpWithColdFactor1()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0, 4000, TimeUnit.Milliseconds, 1.0);

            for (int i = 0; i < 8; i++)
            {
                limiter.Acquire();      // #1
            }
            stopwatch.SleepMillis(340); // #2
            for (int i = 0; i < 8; i++)
            {
                limiter.Acquire();                                                            // #3
            }
            AssertEvents(stopwatch, "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20", // #1
                         "U0.34",                                                             // #2
                         "R0.00, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20, R0.20");           // #3
        }
Esempio n. 23
0
        public void TestWeNeverGetABurstMoreThanOneSec()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 1.0);

            int[] rates = { 1000, 1, 10, 1000000, 10, 1 };
            foreach (var rate in rates)
            {
                int oneSecWorthOfWork = rate;
                stopwatch.SleepMillis(rate * 1000);
                limiter.SetRate(rate);
                long burst = MeasureTotalTimeMillis(stopwatch, limiter, oneSecWorthOfWork, new Random());
                // we allow one second worth of work to go in a burst (i.e. take less than a second)
                Assert.IsTrue(burst <= 1000);
                long afterBurst = MeasureTotalTimeMillis(stopwatch, limiter, oneSecWorthOfWork, new Random());
                // but work beyond that must take at least one second
                Assert.IsTrue(afterBurst >= 1000);
            }
        }
Esempio n. 24
0
        public void TestInfinity_WarmUp()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, double.PositiveInfinity, 10, TimeUnit.Seconds, 3.0);

            limiter.Acquire(int.MaxValue / 4);
            limiter.Acquire(int.MaxValue / 2);
            limiter.Acquire(int.MaxValue);
            AssertEvents(stopwatch, "R0.00", "R0.00", "R0.00");

            limiter.SetRate(1.0);
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            AssertEvents(stopwatch, "R0.00", "R1.00", "R1.00");

            limiter.SetRate(double.PositiveInfinity);
            limiter.Acquire();
            limiter.Acquire();
            limiter.Acquire();
            AssertEvents(stopwatch, "R1.00", "R0.00", "R0.00");
        }
Esempio n. 25
0
        public void TestWarmUpAndUpdateWithColdFactor()
        {
            var stopwatch = new FakeStopwatch();
            var limiter   = RateLimiter.Create(stopwatch, 5.0, 4000, TimeUnit.Milliseconds, 10.0);

            for (var i = 0; i < 8; i++)
            {
                limiter.Acquire();       // #1
            }
            stopwatch.SleepMillis(4200); // #2: back to cold state (warmup period + repay last Acquire)
            for (var i = 0; i < 3; i++)
            {
                // only three steps, we're somewhere in the warmup period
                limiter.Acquire(); // #3
            }

            limiter.SetRate(10.0); // double the rate!
            limiter.Acquire();     // #4, we repay the debt of the last Acquire (imposed by the old rate)
            for (var i = 0; i < 4; i++)
            {
                limiter.Acquire();       // #5
            }
            stopwatch.SleepMillis(4100); // #6, back to cold state (warmup period + repay last Acquire)
            for (var i = 0; i < 11; i++)
            {
                limiter.Acquire(); // #7, showing off the warmup starting from totally cold
            }

            // make sure the areas (times) remain the same, while permits are different
            AssertEvents(stopwatch, "R0.00, R1.75, R1.26, R0.76, R0.30, R0.20, R0.20, R0.20", // #1
                         "U4.20",                                                             // #2
                         "R0.00, R1.75, R1.26",                                               // #3, after that the rate changes
                         "R0.76",                                                             // #4, this is what the throttling would be with the old rate
                         "R0.20, R0.10, R0.10, R0.10",                                        // #5
                         "U4.10",                                                             // #6
                         "R0.00, R0.94, R0.81, R0.69, R0.57, R0.44, R0.32",                   // #7
                         "R0.20, R0.10, R0.10, R0.10");                                       // #7 (cont.), note, this matches #5
        }
Esempio n. 26
0
        public void TestTimeToWarmUpIsHonouredEvenWithWeights()
        {
            var stopwatch         = new FakeStopwatch();
            var random            = new Random();
            var warmupPermits     = 10;
            var coldFactorsToTest = new[] { 2.0, 3.0, 10.0 };
            var qpsToTest         = new[] { 4.0, 2.0, 1.0, 0.5, 0.1 };

            for (var trial = 0; trial < 100; trial++)
            {
                foreach (var coldFactor in coldFactorsToTest)
                {
                    foreach (var qps in qpsToTest)
                    {
                        // If warmupPermits = maxPermits - thresholdPermits then
                        // warmupPeriod = (1 + coldFactor) * warmupPermits * stableInterval / 2
                        var warmupMillis = (long)((1 + coldFactor) * warmupPermits / (2.0 * qps) * 1000.0);
                        var rateLimiter  = RateLimiter.Create(stopwatch, qps, warmupMillis, TimeUnit.Milliseconds, coldFactor);
                        Assert.AreEqual(warmupMillis, MeasureTotalTimeMillis(stopwatch, rateLimiter, warmupPermits, random));
                    }
                }
            }
        }
Esempio n. 27
0
 private void AssertEvents(FakeStopwatch stopwatch, params string[] events)
 {
     Assert.AreEqual(string.Join(", ", events), stopwatch.ReadEventsAndClear());
 }