@Test public void testRateLimiterInitial() { MockClock clock = new MockClock(); clock.timeNanos = TimeUnit.MILLISECONDS.toNanos(-1_000_000); RateLimiter limiter = new RateLimiter(1000, 100, clock); assertTrue(limiter.checkCredit(100)); assertFalse(limiter.checkCredit(1)); clock.timeNanos += TimeUnit.MILLISECONDS.toNanos(49); assertFalse(limiter.checkCredit(50)); clock.timeNanos += TimeUnit.MILLISECONDS.toNanos(1); assertTrue(limiter.checkCredit(50)); assertFalse(limiter.checkCredit(1)); clock.timeNanos += TimeUnit.MILLISECONDS.toNanos(1_000_000); assertTrue(limiter.checkCredit(1)); clock.timeNanos += TimeUnit.MILLISECONDS.toNanos(1_000_000); assertFalse(limiter.checkCredit(101)); assertTrue(limiter.checkCredit(100)); assertFalse(limiter.checkCredit(1)); }
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);  }