private TimeBasedLimiter() { if (FixedIntervalRateLimiter.class.getName().equals( conf.getClass(RateLimiter.QUOTA_RATE_LIMITER_CONF_KEY, AverageIntervalRateLimiter.class) .getName())) { reqsLimiter = new FixedIntervalRateLimiter(); reqSizeLimiter = new FixedIntervalRateLimiter(); writeReqsLimiter = new FixedIntervalRateLimiter(); writeSizeLimiter = new FixedIntervalRateLimiter(); readReqsLimiter = new FixedIntervalRateLimiter(); readSizeLimiter = new FixedIntervalRateLimiter(); reqCapacityUnitLimiter = new FixedIntervalRateLimiter(); writeCapacityUnitLimiter = new FixedIntervalRateLimiter(); readCapacityUnitLimiter = new FixedIntervalRateLimiter(); } else { reqsLimiter = new AverageIntervalRateLimiter(); reqSizeLimiter = new AverageIntervalRateLimiter(); writeReqsLimiter = new AverageIntervalRateLimiter(); writeSizeLimiter = new AverageIntervalRateLimiter(); readReqsLimiter = new AverageIntervalRateLimiter(); readSizeLimiter = new AverageIntervalRateLimiter(); reqCapacityUnitLimiter = new AverageIntervalRateLimiter(); writeCapacityUnitLimiter = new AverageIntervalRateLimiter(); readCapacityUnitLimiter = new AverageIntervalRateLimiter(); } }
@Test public void testLimiterBySmallerRate() throws InterruptedException { // set limiter is 10 resources per seconds RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); int count = 0; // control the test count while ((count++) < 10) { // test will get 3 resources per 0.5 sec. so it will get 6 resources per sec. limiter.setNextRefillTime(limiter.getNextRefillTime() - 500); for (int i = 0; i < 3; i++) { // 6 resources/sec < limit, so limiter.canExecute(nowTs, lastTs) should be true assertEquals(true, limiter.canExecute()); limiter.consume(); } } }
@Test public void testFixedIntervalResourceAvailability() throws Exception { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); assertTrue(limiter.canExecute(10)); limiter.consume(3); assertEquals(7, limiter.getAvailable()); assertFalse(limiter.canExecute(10)); limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000); assertTrue(limiter.canExecute(10)); assertEquals(10, limiter.getAvailable()); }
@Test public void testCanExecuteOfFixedIntervalRateLimiter() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); // when set limit is 100 per sec, this FixedIntervalRateLimiter will support at max 100 per sec limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(50, testCanExecuteByRate(limiter, 50)); // refill the avail to limit limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(100, testCanExecuteByRate(limiter, 100)); // refill the avail to limit limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(100, testCanExecuteByRate(limiter, 200)); }
@Test public void testOverconsumptionFixedIntervalRefillStrategy() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); // fix the current time in order to get the precise value of interval EnvironmentEdge edge = new EnvironmentEdge() { private final long ts = System.currentTimeMillis(); @Override public long currentTime() { return ts; } }; EnvironmentEdgeManager.injectEdge(edge); // 10 resources are available, but we need to consume 20 resources // Verify that we have to wait at least 1.1sec to have 1 resource available assertTrue(limiter.canExecute()); limiter.consume(20); // To consume 1 resource also wait for 1000ms assertEquals(1000, limiter.waitInterval(1)); // To consume 10 resource wait for 100ms assertEquals(1000, limiter.waitInterval(10)); EnvironmentEdgeManager.reset(); limiter.setNextRefillTime(limiter.getNextRefillTime() - 900); // Verify that after 1sec also no resource should be available assertFalse(limiter.canExecute(1)); limiter.setNextRefillTime(limiter.getNextRefillTime() - 100); // Verify that after 1sec the 10 resource is available assertTrue(limiter.canExecute()); assertEquals(0, limiter.waitInterval()); }
@Test public void testRefillOfFixedIntervalRateLimiter() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(60, TimeUnit.SECONDS); assertEquals(60, limiter.getAvailable()); // first refill, will return the number same with limit assertEquals(60, limiter.refill(limiter.getLimit())); limiter.consume(30); // after 0.2 sec, refill should return 0 limiter.setNextRefillTime(limiter.getNextRefillTime() - 200); assertEquals(0, limiter.refill(limiter.getLimit())); // after 0.5 sec, refill should return 0 limiter.setNextRefillTime(limiter.getNextRefillTime() - 500); assertEquals(0, limiter.refill(limiter.getLimit())); // after 1 sec, refill should return 60 limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000); assertEquals(60, limiter.refill(limiter.getLimit())); // after more than 1 sec, refill should return at max 60 limiter.setNextRefillTime(limiter.getNextRefillTime() - 3000); assertEquals(60, limiter.refill(limiter.getLimit())); limiter.setNextRefillTime(limiter.getNextRefillTime() - 5000); assertEquals(60, limiter.refill(limiter.getLimit())); }
@Test public void testUnconfiguredLimiters() throws InterruptedException { ManualEnvironmentEdge testEdge = new ManualEnvironmentEdge(); EnvironmentEdgeManager.injectEdge(testEdge); long limit = Long.MAX_VALUE; // For unconfigured limiters, it is supposed to use as much as possible RateLimiter avgLimiter = new AverageIntervalRateLimiter(); RateLimiter fixLimiter = new FixedIntervalRateLimiter(); assertEquals(limit, avgLimiter.getAvailable()); assertEquals(limit, fixLimiter.getAvailable()); assertTrue(avgLimiter.canExecute(limit)); avgLimiter.consume(limit); assertTrue(fixLimiter.canExecute(limit)); fixLimiter.consume(limit); // Make sure that available is Long.MAX_VALUE assertTrue(limit == avgLimiter.getAvailable()); assertTrue(limit == fixLimiter.getAvailable()); // after 100 millseconds, it should be able to execute limit as well testEdge.incValue(100); assertTrue(avgLimiter.canExecute(limit)); avgLimiter.consume(limit); assertTrue(fixLimiter.canExecute(limit)); fixLimiter.consume(limit); // Make sure that available is Long.MAX_VALUE assertTrue(limit == avgLimiter.getAvailable()); assertTrue(limit == fixLimiter.getAvailable()); EnvironmentEdgeManager.reset(); }
RateLimiter fixLimiter = new FixedIntervalRateLimiter(); fixLimiter.set(limit, TimeUnit.SECONDS);
private TimeBasedLimiter() { if (FixedIntervalRateLimiter.class.getName().equals( conf.getClass(RateLimiter.QUOTA_RATE_LIMITER_CONF_KEY, AverageIntervalRateLimiter.class) .getName())) { reqsLimiter = new FixedIntervalRateLimiter(); reqSizeLimiter = new FixedIntervalRateLimiter(); writeReqsLimiter = new FixedIntervalRateLimiter(); writeSizeLimiter = new FixedIntervalRateLimiter(); readReqsLimiter = new FixedIntervalRateLimiter(); readSizeLimiter = new FixedIntervalRateLimiter(); } else { reqsLimiter = new AverageIntervalRateLimiter(); reqSizeLimiter = new AverageIntervalRateLimiter(); writeReqsLimiter = new AverageIntervalRateLimiter(); writeSizeLimiter = new AverageIntervalRateLimiter(); readReqsLimiter = new AverageIntervalRateLimiter(); readSizeLimiter = new AverageIntervalRateLimiter(); } }
@Test public void testLimiterBySmallerRate() throws InterruptedException { // set limiter is 10 resources per seconds RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); int count = 0; // control the test count while ((count++) < 10) { // test will get 3 resources per 0.5 sec. so it will get 6 resources per sec. limiter.setNextRefillTime(limiter.getNextRefillTime() - 500); for (int i = 0; i < 3; i++) { // 6 resources/sec < limit, so limiter.canExecute(nowTs, lastTs) should be true assertEquals(true, limiter.canExecute()); limiter.consume(); } } }
@Test public void testFixedIntervalResourceAvailability() throws Exception { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); assertTrue(limiter.canExecute(10)); limiter.consume(3); assertEquals(7, limiter.getAvailable()); assertFalse(limiter.canExecute(10)); limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000); assertTrue(limiter.canExecute(10)); assertEquals(10, limiter.getAvailable()); }
@Test public void testCanExecuteOfFixedIntervalRateLimiter() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); // when set limit is 100 per sec, this FixedIntervalRateLimiter will support at max 100 per sec limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(50, testCanExecuteByRate(limiter, 50)); // refill the avail to limit limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(100, testCanExecuteByRate(limiter, 100)); // refill the avail to limit limiter.set(100, TimeUnit.SECONDS); limiter.setNextRefillTime(EnvironmentEdgeManager.currentTime()); assertEquals(100, testCanExecuteByRate(limiter, 200)); }
@Test public void testOverconsumptionFixedIntervalRefillStrategy() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(10, TimeUnit.SECONDS); // fix the current time in order to get the precise value of interval EnvironmentEdge edge = new EnvironmentEdge() { private final long ts = System.currentTimeMillis(); @Override public long currentTime() { return ts; } }; EnvironmentEdgeManager.injectEdge(edge); // 10 resources are available, but we need to consume 20 resources // Verify that we have to wait at least 1.1sec to have 1 resource available assertTrue(limiter.canExecute()); limiter.consume(20); // To consume 1 resource also wait for 1000ms assertEquals(1000, limiter.waitInterval(1)); // To consume 10 resource wait for 100ms assertEquals(1000, limiter.waitInterval(10)); EnvironmentEdgeManager.reset(); limiter.setNextRefillTime(limiter.getNextRefillTime() - 900); // Verify that after 1sec also no resource should be available assertFalse(limiter.canExecute(1)); limiter.setNextRefillTime(limiter.getNextRefillTime() - 100); // Verify that after 1sec the 10 resource is available assertTrue(limiter.canExecute()); assertEquals(0, limiter.waitInterval()); }
@Test public void testUnconfiguredLimiters() throws InterruptedException { ManualEnvironmentEdge testEdge = new ManualEnvironmentEdge(); EnvironmentEdgeManager.injectEdge(testEdge); long limit = Long.MAX_VALUE; // For unconfigured limiters, it is supposed to use as much as possible RateLimiter avgLimiter = new AverageIntervalRateLimiter(); RateLimiter fixLimiter = new FixedIntervalRateLimiter(); assertEquals(limit, avgLimiter.getAvailable()); assertEquals(limit, fixLimiter.getAvailable()); assertTrue(avgLimiter.canExecute(limit)); avgLimiter.consume(limit); assertTrue(fixLimiter.canExecute(limit)); fixLimiter.consume(limit); // Make sure that available is Long.MAX_VALUE assertTrue(limit == avgLimiter.getAvailable()); assertTrue(limit == fixLimiter.getAvailable()); // after 100 millseconds, it should be able to execute limit as well testEdge.incValue(100); assertTrue(avgLimiter.canExecute(limit)); avgLimiter.consume(limit); assertTrue(fixLimiter.canExecute(limit)); fixLimiter.consume(limit); // Make sure that available is Long.MAX_VALUE assertTrue(limit == avgLimiter.getAvailable()); assertTrue(limit == fixLimiter.getAvailable()); EnvironmentEdgeManager.reset(); }
@Test public void testRefillOfFixedIntervalRateLimiter() throws InterruptedException { RateLimiter limiter = new FixedIntervalRateLimiter(); limiter.set(60, TimeUnit.SECONDS); assertEquals(60, limiter.getAvailable()); // first refill, will return the number same with limit assertEquals(60, limiter.refill(limiter.getLimit())); limiter.consume(30); // after 0.2 sec, refill should return 0 limiter.setNextRefillTime(limiter.getNextRefillTime() - 200); assertEquals(0, limiter.refill(limiter.getLimit())); // after 0.5 sec, refill should return 0 limiter.setNextRefillTime(limiter.getNextRefillTime() - 500); assertEquals(0, limiter.refill(limiter.getLimit())); // after 1 sec, refill should return 60 limiter.setNextRefillTime(limiter.getNextRefillTime() - 1000); assertEquals(60, limiter.refill(limiter.getLimit())); // after more than 1 sec, refill should return at max 60 limiter.setNextRefillTime(limiter.getNextRefillTime() - 3000); assertEquals(60, limiter.refill(limiter.getLimit())); limiter.setNextRefillTime(limiter.getNextRefillTime() - 5000); assertEquals(60, limiter.refill(limiter.getLimit())); }
RateLimiter fixLimiter = new FixedIntervalRateLimiter(); fixLimiter.set(limit, TimeUnit.SECONDS);