Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Commit

Permalink
respect max backoff itme
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Ziebart committed Nov 15, 2017
1 parent 2318f69 commit c7dff29
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ SerializableTransactionManager serializable() {

private QosClient getQosClient(QosClientConfig config) {
// TODO(nziebart): create a RefreshingRateLimiter
QosRateLimiters rateLimiters = QosRateLimiters.create(config.limits());
QosRateLimiters rateLimiters = QosRateLimiters.create(
config.limits(),
config.maxBackoffSleepTime().toMilliseconds());
return AtlasDbQosClient.create(rateLimiters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,22 @@ public class QosRateLimiter {

private static final double MAX_BURST_SECONDS = 5;
private static final double UNLIMITED_RATE = Double.MAX_VALUE;
private static final int MAX_WAIT_TIME_SECONDS = 10;

private final long maxBackoffTimeMillis;
private RateLimiter rateLimiter;

public static QosRateLimiter create() {
return new QosRateLimiter(RateLimiter.SleepingStopwatch.createFromSystemTimer());
public static QosRateLimiter create(long maxBackoffTimeMillis) {
return new QosRateLimiter(RateLimiter.SleepingStopwatch.createFromSystemTimer(), maxBackoffTimeMillis);
}

@VisibleForTesting
QosRateLimiter(RateLimiter.SleepingStopwatch stopwatch) {
QosRateLimiter(RateLimiter.SleepingStopwatch stopwatch, long maxBackoffTimeMillis) {
rateLimiter = new SmoothRateLimiter.SmoothBursty(
stopwatch,
MAX_BURST_SECONDS);

rateLimiter.setRate(UNLIMITED_RATE);
this.maxBackoffTimeMillis = maxBackoffTimeMillis;
}

/**
Expand All @@ -67,8 +68,8 @@ public void updateRate(int unitsPerSecond) {
public Duration consumeWithBackoff(int estimatedNumUnits) {
Optional<Duration> waitTime = rateLimiter.tryAcquire(
estimatedNumUnits,
MAX_WAIT_TIME_SECONDS,
TimeUnit.SECONDS);
maxBackoffTimeMillis,
TimeUnit.MILLISECONDS);

if (!waitTime.isPresent()) {
throw new RuntimeException("rate limited");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
@Value.Immutable
public interface QosRateLimiters {

static QosRateLimiters create(QosLimitsConfig config) {
QosRateLimiter readLimiter = QosRateLimiter.create();
static QosRateLimiters create(QosLimitsConfig config, long maxBackoffSleepTimeMillis) {
QosRateLimiter readLimiter = QosRateLimiter.create(maxBackoffSleepTimeMillis);
readLimiter.updateRate(config.readBytesPerSecond());

QosRateLimiter writeLimiter = QosRateLimiter.create();
QosRateLimiter writeLimiter = QosRateLimiter.create(maxBackoffSleepTimeMillis);
writeLimiter.updateRate(config.writeBytesPerSecond());

return ImmutableQosRateLimiters.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
public class QosRateLimiterTest {

private static final long START_TIME_MICROS = 0L;
private static final long MAX_BACKOFF_TIME_MILLIS = 10_000;

RateLimiter.SleepingStopwatch stopwatch = mock(RateLimiter.SleepingStopwatch.class);
QosRateLimiter limiter = new QosRateLimiter(stopwatch);
QosRateLimiter limiter = new QosRateLimiter(stopwatch, MAX_BACKOFF_TIME_MILLIS);

@Before
public void before() {
Expand Down Expand Up @@ -63,6 +64,15 @@ public void limitsByThrowingIfSleepTimeIsTooGreat() {
.hasMessageContaining("rate limited");
}

@Test
public void doesNotThrowIfMaxBackoffTimeIsVeryLarge() {
QosRateLimiter limiterWithLargeBackoffLimit = new QosRateLimiter(stopwatch, Long.MAX_VALUE);
limiterWithLargeBackoffLimit.updateRate(10);

limiterWithLargeBackoffLimit.consumeWithBackoff(1_000_000_000);
limiterWithLargeBackoffLimit.consumeWithBackoff(1_000_000_000);
}

@Test
public void consumingAdditionalUnitsPenalizesFutureCallers() {
limiter.updateRate(10);
Expand Down

0 comments on commit c7dff29

Please sign in to comment.