Skip to content

Commit 3e38109

Browse files
committed
chore: bring backoff behavior inline with RetryHelper
Specifically, only return exhausted when the timeout has elapsed.
1 parent 8453281 commit 3e38109

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

google-cloud-storage/src/main/java/com/google/cloud/storage/Backoff.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,16 @@ private Backoff(
8181
*
8282
* <ol>
8383
* <li>If the existing {@link #cumulativeBackoff} + {@code elapsed} is >= {@link #timeout}
84-
* <li>If the existing {@link #cumulativeBackoff} + {@code elapsed} + {@code
85-
* nextBackoffDuration} is >= {@link #timeout}
8684
* </ol>
8785
*/
8886
BackoffResult nextBackoff(Duration elapsed) {
8987
checkArgument(
9088
Durations.gtEq(elapsed, ZERO), "elapsed must be >= PT0S (%s >= %s)", elapsed, ZERO);
9189
Duration cumulativeAndElapsed = cumulativeBackoff.plus(elapsed);
90+
if (Durations.gtEq(cumulativeAndElapsed, timeout)) {
91+
cumulativeBackoff = cumulativeAndElapsed;
92+
return BackoffResults.EXHAUSTED;
93+
}
9294

9395
Duration nextDelay =
9496
Duration.ofNanos(Math.round(previousBackoff.toNanos() * retryDelayMultiplier));
@@ -97,15 +99,10 @@ BackoffResult nextBackoff(Duration elapsed) {
9799
}
98100
Duration nextBackoffWithJitter = jitterer.jitter(nextDelay);
99101
Duration cappedBackoff = Durations.min(nextBackoffWithJitter, maxBackoff);
100-
Duration newCumulativeElapsed = cumulativeAndElapsed.plus(cappedBackoff);
101-
cumulativeBackoff = newCumulativeElapsed;
102+
cumulativeBackoff = cumulativeAndElapsed.plus(cappedBackoff);
102103
previousBackoff = cappedBackoff;
103104

104-
if (Durations.gtEq(newCumulativeElapsed, timeout)) {
105-
return BackoffResults.EXHAUSTED;
106-
} else {
107-
return BackoffDuration.of(cappedBackoff);
108-
}
105+
return BackoffDuration.of(cappedBackoff);
109106
}
110107

111108
/**

google-cloud-storage/src/test/java/com/google/cloud/storage/BackoffTest.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static com.google.common.truth.Truth.assertThat;
2020
import static java.time.Duration.ZERO;
21+
import static java.time.Duration.ofSeconds;
2122
import static org.junit.Assert.assertThrows;
2223

2324
import com.google.cloud.storage.Backoff.BackoffDuration;
@@ -83,15 +84,17 @@ public void simple() {
8384
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57)));
8485
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57)));
8586
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57)));
87+
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57)));
8688
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffResults.EXHAUSTED);
8789
}
8890

8991
@Test
90-
public void happyPath() {
92+
public void backoffDuration_min_of_backoff_maxBackoff_remainingFromTimeout() {
9193
Backoff backoff = defaultBackoff();
9294

9395
Duration elapsed = Duration.ofMinutes(6).plusSeconds(58);
94-
assertThat(backoff.nextBackoff(elapsed)).isEqualTo(BackoffResults.EXHAUSTED);
96+
assertThat(backoff.nextBackoff(elapsed)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2)));
97+
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffResults.EXHAUSTED);
9598
}
9699

97100
@Test
@@ -116,7 +119,8 @@ public void resetWorks() {
116119
.setRetryDelayMultiplier(2.0)
117120
.build();
118121

119-
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2)));
122+
assertThat(backoff.nextBackoff(Duration.ofSeconds(4)))
123+
.isEqualTo(BackoffDuration.of(Duration.ofSeconds(2)));
120124
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffResults.EXHAUSTED);
121125
backoff.reset();
122126
assertThat(backoff.nextBackoff(Duration.ofSeconds(10))).isEqualTo(BackoffResults.EXHAUSTED);
@@ -139,8 +143,14 @@ public void onceExhaustedStaysExhaustedUntilReset() {
139143
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2)));
140144
}
141145

146+
/**
147+
* If a next computed backoff would exceed the timeout, truncate the backoff to the amount of time
148+
* remaining until timeout.
149+
*
150+
* <p>This is primarily here to preserve behavior of {@link com.google.cloud.RetryHelper}.
151+
*/
142152
@Test
143-
public void ifANextBackoffWouldExceedTheTimeoutItShouldBeConsideredExhausted() {
153+
public void ifANextBackoffWouldExceedTheTimeoutTheBackoffDurationShouldBeTruncated() {
144154
Backoff backoff =
145155
Backoff.newBuilder()
146156
.setInitialBackoff(Duration.ofSeconds(2))
@@ -150,10 +160,9 @@ public void ifANextBackoffWouldExceedTheTimeoutItShouldBeConsideredExhausted() {
150160
.setRetryDelayMultiplier(2.0)
151161
.build();
152162

153-
assertThat(backoff.nextBackoff(Duration.ofSeconds(5)))
154-
.isEqualTo(BackoffDuration.of(Duration.ofSeconds(2)));
155-
156-
assertThat(backoff.nextBackoff(Duration.ofSeconds(15))).isEqualTo(BackoffResults.EXHAUSTED);
163+
assertThat(backoff.nextBackoff(Duration.ofSeconds(22)))
164+
.isEqualTo(BackoffDuration.of(ofSeconds(2)));
165+
assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffResults.EXHAUSTED);
157166
}
158167

159168
@Test

0 commit comments

Comments
 (0)