Support sub-millisecond permit regeneration durations in rate limiters

This commit is contained in:
Jon Chambers 2023-07-14 14:38:07 -04:00 committed by Jon Chambers
parent 82ed783a2d
commit e38a713ccc
3 changed files with 11 additions and 4 deletions

View File

@ -11,11 +11,16 @@ import java.time.Duration;
public record RateLimiterConfig(int bucketSize, Duration permitRegenerationDuration) {
public double leakRatePerMillis() {
return 1.0 / permitRegenerationDuration.toMillis();
return 1.0 / (permitRegenerationDuration.toNanos() / 1e6);
}
@AssertTrue
public boolean hasPositiveRegenerationRate() {
return permitRegenerationDuration.toMillis() > 0;
try {
return permitRegenerationDuration.toNanos() > 0;
} catch (final ArithmeticException e) {
// The duration was too large to fit in a long, so it's definitely positive
return true;
}
}
}

View File

@ -302,7 +302,7 @@ class DynamicConfigurationTest {
limits:
rateLimitReset:
bucketSize: 17
permitRegenerationDuration: PT4S
permitRegenerationDuration: PT0.000004S
""");
final RateLimiterConfig resetRateLimiterConfig =
@ -310,7 +310,7 @@ class DynamicConfigurationTest {
.getLimits().get(RateLimiters.For.RATE_LIMIT_RESET.id());
assertThat(resetRateLimiterConfig.bucketSize()).isEqualTo(17);
assertThat(resetRateLimiterConfig.permitRegenerationDuration()).isEqualTo(Duration.ofSeconds(4));
assertThat(resetRateLimiterConfig.permitRegenerationDuration()).isEqualTo(Duration.ofNanos(4_000));
}
@Test

View File

@ -17,11 +17,13 @@ class RateLimiterConfigTest {
@Test
void leakRatePerMillis() {
assertEquals(0.001, new RateLimiterConfig(1, Duration.ofSeconds(1)).leakRatePerMillis());
assertEquals(1e6, new RateLimiterConfig(1, Duration.ofNanos(1)).leakRatePerMillis());
}
@Test
void isRegenerationRatePositive() {
assertTrue(new RateLimiterConfig(1, Duration.ofSeconds(1)).hasPositiveRegenerationRate());
assertTrue(new RateLimiterConfig(1, Duration.ofNanos(1)).hasPositiveRegenerationRate());
assertFalse(new RateLimiterConfig(1, Duration.ZERO).hasPositiveRegenerationRate());
assertFalse(new RateLimiterConfig(1, Duration.ofSeconds(-1)).hasPositiveRegenerationRate());
}