@Test public void testRateLimiterWholeNumber() { MockClock clock = new MockClock(); RateLimiter limiter = new RateLimiter(2.0, 2.0, clock); long currentTime = TimeUnit.MICROSECONDS.toNanos(100); clock.timeNanos = currentTime; assertTrue(limiter.checkCredit(1.0)); assertTrue(limiter.checkCredit(1.0)); assertFalse(limiter.checkCredit(1.0)); currentTime += TimeUnit.MILLISECONDS.toNanos(250); clock.timeNanos = currentTime; assertFalse(limiter.checkCredit(1.0)); currentTime += TimeUnit.MILLISECONDS.toNanos(500); clock.timeNanos = currentTime; assertTrue(limiter.checkCredit(1.0)); assertFalse(limiter.checkCredit(1.0)); currentTime += TimeUnit.MILLISECONDS.toNanos(5000); clock.timeNanos = currentTime; assertTrue(limiter.checkCredit(1.0)); assertTrue(limiter.checkCredit(1.0)); assertFalse(limiter.checkCredit(1.0)); assertFalse(limiter.checkCredit(1.0)); assertFalse(limiter.checkCredit(1.0)); }
public boolean checkCredit(double itemCost) { long cost = (long) (itemCost / creditsPerNanosecond); long credit; long currentDebit; long balance; do { currentDebit = debit.get(); credit = clock.currentNanoTicks(); balance = credit - currentDebit; if (balance > maxBalance) { balance = maxBalance; } balance -= cost; if (balance < 0) { return false; } } while (!debit.compareAndSet(currentDebit, credit - balance)); return true; }
RateLimiter { public boolean checkCredit(double itemCost) { long cost = (long) (itemCost / creditsPerNanosecond); long credit; long currentDebit; long balance; do { currentDebit = debit.get(); credit = clock.currentNanoTicks(); balance = credit - currentDebit; if (balance > maxBalance) { balance = maxBalance; } balance -= cost; if (balance < 0) { return false; } } while (!debit.compareAndSet(currentDebit, credit - balance)); return true; } }
RateLimiter { public boolean checkCredit(double itemCost) { long cost = (long) (itemCost / creditsPerNanosecond); long credit; long currentDebit; long balance; do { currentDebit = debit.get(); credit = clock.currentNanoTicks(); balance = credit - currentDebit; if (balance > maxBalance) { balance = maxBalance; } balance -= cost; if (balance < 0) { return false; } } while (!debit.compareAndSet(currentDebit, credit - balance)); return true; } RateLimiter(double creditsPerSecond, double maxBalance);  RateLimiter(double creditsPerSecond, double maxBalance, Clock clock); }
RateLimiter { public boolean checkCredit(double itemCost) { long cost = (long) (itemCost / creditsPerNanosecond); long credit; long currentDebit; long balance; do { currentDebit = debit.get(); credit = clock.currentNanoTicks(); balance = credit - currentDebit; if (balance > maxBalance) { balance = maxBalance; } balance -= cost; if (balance < 0) { return false; } } while (!debit.compareAndSet(currentDebit, credit - balance)); return true; } RateLimiter(double creditsPerSecond, double maxBalance);  RateLimiter(double creditsPerSecond, double maxBalance, Clock clock); boolean checkCredit(double itemCost); }
RateLimiter { public boolean checkCredit(double itemCost) { long cost = (long) (itemCost / creditsPerNanosecond); long credit; long currentDebit; long balance; do { currentDebit = debit.get(); credit = clock.currentNanoTicks(); balance = credit - currentDebit; if (balance > maxBalance) { balance = maxBalance; } balance -= cost; if (balance < 0) { return false; } } while (!debit.compareAndSet(currentDebit, credit - balance)); return true; } RateLimiter(double creditsPerSecond, double maxBalance);  RateLimiter(double creditsPerSecond, double maxBalance, Clock clock); boolean checkCredit(double itemCost);  }