@Test public void reservePermissionsUpfront() throws Exception { final int limitForPeriod = 3; final int tasksNum = 9; Duration limitRefreshPeriod = Duration.ofMillis(10); Duration timeoutDuration = Duration.ofMillis(12); long cycleInNanos = limitRefreshPeriod.toNanos(); setup(limitRefreshPeriod, timeoutDuration, limitForPeriod); setTimeOnNanos(cycleInNanos); ArrayList<Long> timesToWait = new ArrayList<>(); for (int i = 0; i < tasksNum; i++) { setTimeOnNanos(cycleInNanos + i + 1); long timeToWait = rateLimiter.reservePermission(1); timesToWait.add(timeToWait); } then(timesToWait).containsExactly( 0L, 0L, 0L, cycleInNanos - 4, cycleInNanos - 5, cycleInNanos - 6, -1L, -1L, -1L ); }
@Override public long reservePermission(final int permits) { long timeoutInNanos = state.get().config.getTimeoutDuration().toNanos(); State modifiedState = updateStateWithBackOff(permits, timeoutInNanos); boolean canAcquireImmediately = modifiedState.nanosToWait <= 0; if (canAcquireImmediately) { publishRateLimiterEvent(true, permits); return 0; } boolean canAcquireInTime = timeoutInNanos >= modifiedState.nanosToWait; if (canAcquireInTime) { publishRateLimiterEvent(true, permits); return modifiedState.nanosToWait; } publishRateLimiterEvent(false, permits); return -1; }
AtomicRateLimiter implements RateLimiter { @Override public long reservePermission(final int permits) { long timeoutInNanos = state.get().config.getTimeoutDuration().toNanos(); State modifiedState = updateStateWithBackOff(permits, timeoutInNanos); boolean canAcquireImmediately = modifiedState.nanosToWait <= 0; if (canAcquireImmediately) { publishRateLimiterEvent(true, permits); return 0; } boolean canAcquireInTime = timeoutInNanos >= modifiedState.nanosToWait; if (canAcquireInTime) { publishRateLimiterEvent(true, permits); return modifiedState.nanosToWait; } publishRateLimiterEvent(false, permits); return -1; } }
AtomicRateLimiter implements RateLimiter { @Override public long reservePermission(final int permits) { long timeoutInNanos = state.get().config.getTimeoutDuration().toNanos(); State modifiedState = updateStateWithBackOff(permits, timeoutInNanos); boolean canAcquireImmediately = modifiedState.nanosToWait <= 0; if (canAcquireImmediately) { publishRateLimiterEvent(true, permits); return 0; } boolean canAcquireInTime = timeoutInNanos >= modifiedState.nanosToWait; if (canAcquireInTime) { publishRateLimiterEvent(true, permits); return modifiedState.nanosToWait; } publishRateLimiterEvent(false, permits); return -1; } AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig);  AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig,
                             Map<String, String> tags); }
AtomicRateLimiter implements RateLimiter { @Override public long reservePermission(final int permits) { long timeoutInNanos = state.get().config.getTimeoutDuration().toNanos(); State modifiedState = updateStateWithBackOff(permits, timeoutInNanos); boolean canAcquireImmediately = modifiedState.nanosToWait <= 0; if (canAcquireImmediately) { publishRateLimiterEvent(true, permits); return 0; } boolean canAcquireInTime = timeoutInNanos >= modifiedState.nanosToWait; if (canAcquireInTime) { publishRateLimiterEvent(true, permits); return modifiedState.nanosToWait; } publishRateLimiterEvent(false, permits); return -1; } AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig);  AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig,
                             Map<String, String> tags); @Override void changeTimeoutDuration(final Duration timeoutDuration); @Override void changeLimitForPeriod(final int limitForPeriod); @Override boolean acquirePermission(final int permits); @Override long reservePermission(final int permits); @Override String getName(); @Override RateLimiterConfig getRateLimiterConfig(); @Override Map<String, String> getTags(); @Override Metrics getMetrics(); @Override EventPublisher getEventPublisher(); @Override String toString(); AtomicRateLimiterMetrics getDetailedMetrics(); }
AtomicRateLimiter implements RateLimiter { @Override public long reservePermission(final int permits) { long timeoutInNanos = state.get().config.getTimeoutDuration().toNanos(); State modifiedState = updateStateWithBackOff(permits, timeoutInNanos); boolean canAcquireImmediately = modifiedState.nanosToWait <= 0; if (canAcquireImmediately) { publishRateLimiterEvent(true, permits); return 0; } boolean canAcquireInTime = timeoutInNanos >= modifiedState.nanosToWait; if (canAcquireInTime) { publishRateLimiterEvent(true, permits); return modifiedState.nanosToWait; } publishRateLimiterEvent(false, permits); return -1; } AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig);  AtomicRateLimiter(String name, RateLimiterConfig rateLimiterConfig,
                             Map<String, String> tags); @Override void changeTimeoutDuration(final Duration timeoutDuration); @Override void changeLimitForPeriod(final int limitForPeriod); @Override boolean acquirePermission(final int permits); @Override long reservePermission(final int permits); @Override String getName(); @Override RateLimiterConfig getRateLimiterConfig(); @Override Map<String, String> getTags(); @Override Metrics getMetrics(); @Override EventPublisher getEventPublisher(); @Override String toString(); AtomicRateLimiterMetrics getDetailedMetrics();  }