From 203ebf2eff6a4a0ebd28f5b7b1e7798a5da91205 Mon Sep 17 00:00:00 2001 From: lcy Date: Mon, 3 Aug 2026 19:35:24 +0800 Subject: [PATCH 1/2] Handle zero warmup periods in RateLimiter Add documentation for warmup period in RateLimiter. --- .../com/google/common/util/concurrent/RateLimiter.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/guava/src/com/google/common/util/concurrent/RateLimiter.java b/guava/src/com/google/common/util/concurrent/RateLimiter.java index 981238746d3c..0b6502a7e2ac 100644 --- a/guava/src/com/google/common/util/concurrent/RateLimiter.java +++ b/guava/src/com/google/common/util/concurrent/RateLimiter.java @@ -156,6 +156,8 @@ static RateLimiter create(double permitsPerSecond, SleepingStopwatch stopwatch) *

The returned {@code RateLimiter} starts in a "cold" state (i.e. the warmup period will * follow), and if it is left unused for long enough, it will return to that state. * + *

A {@code warmupPeriod} of zero is equivalent to {@link #create(double)}. + * * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in how many * permits become available per second * @param warmupPeriod the duration of the period where the {@code RateLimiter} ramps up its rate, @@ -184,6 +186,8 @@ public static RateLimiter create(double permitsPerSecond, Duration warmupPeriod) *

The returned {@code RateLimiter} starts in a "cold" state (i.e. the warmup period will * follow), and if it is left unused for long enough, it will return to that state. * + *

A {@code warmupPeriod} of zero is equivalent to {@link #create(double)}. + * * @param permitsPerSecond the rate of the returned {@code RateLimiter}, measured in how many * permits become available per second * @param warmupPeriod the duration of the period where the {@code RateLimiter} ramps up its rate, @@ -206,6 +210,11 @@ static RateLimiter create( TimeUnit unit, double coldFactor, SleepingStopwatch stopwatch) { + checkNotNull(unit); + // SmoothWarmingUp operates in microseconds and cannot represent a shorter warmup period. + if (warmupPeriod>= 0 && unit.toMicros(warmupPeriod) == 0) { + return create(permitsPerSecond, stopwatch); + } RateLimiter rateLimiter = new SmoothWarmingUp(stopwatch, warmupPeriod, unit, coldFactor); rateLimiter.setRate(permitsPerSecond); return rateLimiter; From 14fcb2478f85cb3790c2b6fffe33c2f83c902cef Mon Sep 17 00:00:00 2001 From: lcy Date: Mon, 3 Aug 2026 19:36:16 +0800 Subject: [PATCH 2/2] Add zero warmup RateLimiter tests Add tests to verify behavior of RateLimiter with zero and sub-microsecond warmup durations. --- .../util/concurrent/RateLimiterTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java index 0be7e2659d91..73273635ea99 100644 --- a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java +++ b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java @@ -34,6 +34,7 @@ import com.google.common.testing.NullPointerTester.Visibility; import com.google.common.util.concurrent.RateLimiter.SleepingStopwatch; import java.lang.reflect.Method; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -154,6 +155,32 @@ public void testCreateWarmupParameterValidation() { assertThrows(IllegalArgumentException.class, () -> RateLimiter.create(1.0, -1, NANOSECONDS)); } + public void testZeroWarmupIsEquivalentToNoWarmup() { + RateLimiter limiter = RateLimiter.create(5.0, 0, SECONDS, 3.0, stopwatch); + limiter.acquire(); + limiter.acquire(); + limiter.acquire(); + assertEvents("R0.00", "R0.20", "R0.20"); + } + + public void testZeroDurationWarmupIsEquivalentToNoWarmup() { + RateLimiter limiter = RateLimiter.create(Double.MIN_VALUE, Duration.ZERO); + assertTrue(limiter.tryAcquire()); + assertFalse(limiter.tryAcquire()); + } + + public void testSubMicrosecondWarmupIsEquivalentToNoWarmup() { + RateLimiter limiter = RateLimiter.create(Double.MIN_VALUE, 1, NANOSECONDS); + assertTrue(limiter.tryAcquire()); + assertFalse(limiter.tryAcquire()); + } + + public void testSubMicrosecondDurationWarmupIsEquivalentToNoWarmup() { + RateLimiter limiter = RateLimiter.create(Double.MIN_VALUE, Duration.ofNanos(1)); + assertTrue(limiter.tryAcquire()); + assertFalse(limiter.tryAcquire()); + } + @AndroidIncompatible // difference in String.format rounding? public void testWarmUp() { RateLimiter limiter = RateLimiter.create(2.0, 4000, MILLISECONDS, 3.0, stopwatch);

AltStyle によって変換されたページ (->オリジナル) /