Skip to content

Commit 8e6bfdf

Browse files
authored
Merge pull request #2118 from jponge/fix/2117
fix: propagate the last failure in expiring retries
2 parents be94c13 + 1fb6331 commit 8e6bfdf

2 files changed

Lines changed: 45 additions & 7 deletions

File tree

implementation/src/main/java/io/smallrye/mutiny/helpers/ExponentialBackoff.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ public Publisher<Long> apply(Multi<Throwable> t) {
117117

118118
long checkTime = System.currentTimeMillis() + delay.toMillis();
119119
if (checkTime > expireAt) {
120-
return Uni.createFrom().failure(
120+
failure.addSuppressed(
121121
new IllegalStateException(
122122
"Retries exhausted : " + iteration + " attempts against " + checkTime + "/" + expireAt
123-
+ " expiration",
124-
failure));
123+
+ " expiration"));
124+
return Uni.createFrom().failure(failure);
125125
}
126126
return Uni.createFrom().item((long) iteration).onItem().delayIt()
127127
.onExecutor(executor).by(delay);

implementation/src/test/java/io/smallrye/mutiny/groups/UniOnFailureRetryTest.java

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,62 @@ public void testRetryWithBackOffReachingMaxAttempt() {
216216

217217
@Test
218218
public void testRetryWithBackOffReachingExpiresIn() {
219-
assertThrows(IllegalStateException.class, () -> {
219+
assertThatThrownBy(() -> {
220220
AtomicInteger count = new AtomicInteger();
221221
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
222222
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
223223
.expireIn(90L)
224224
.await().atMost(Duration.ofSeconds(5));
225-
});
225+
}).cause()
226+
.hasMessageContaining("boom")
227+
.satisfies(t -> assertThat(t.getSuppressed())
228+
.hasSize(1)
229+
.allSatisfy(s -> assertThat(s)
230+
.isInstanceOf(IllegalStateException.class)
231+
.hasMessageContaining("Retries exhausted")));
226232
}
227233

228234
@Test
229235
public void testRetryWithBackOffReachingExpiresAt() {
230-
assertThrows(IllegalStateException.class, () -> {
236+
assertThatThrownBy(() -> {
231237
AtomicInteger count = new AtomicInteger();
232238
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
233239
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
234240
.expireAt(System.currentTimeMillis() + 90L)
235241
.await().atMost(Duration.ofSeconds(5));
236-
});
242+
}).cause()
243+
.hasMessageContaining("boom")
244+
.satisfies(t -> assertThat(t.getSuppressed())
245+
.hasSize(1)
246+
.allSatisfy(s -> assertThat(s)
247+
.isInstanceOf(IllegalStateException.class)
248+
.hasMessageContaining("Retries exhausted")));
249+
}
250+
251+
@Test
252+
public void testRetryWithBackOffReachingExpiresInPropagatesLastFailure() {
253+
assertThatThrownBy(() -> {
254+
AtomicInteger count = new AtomicInteger();
255+
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
256+
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
257+
.expireIn(90L)
258+
.await().atMost(Duration.ofSeconds(5));
259+
}).isNotInstanceOf(IllegalStateException.class)
260+
.cause()
261+
.hasMessageContaining("boom");
262+
}
263+
264+
@Test
265+
public void testRetryWithBackOffReachingExpiresAtPropagatesLastFailure() {
266+
assertThatThrownBy(() -> {
267+
AtomicInteger count = new AtomicInteger();
268+
Uni.createFrom().<String> emitter(e -> e.fail(new Exception("boom " + count.getAndIncrement())))
269+
.onFailure().retry().withBackOff(Duration.ofMillis(10), Duration.ofSeconds(20)).withJitter(1.0)
270+
.expireAt(System.currentTimeMillis() + 90L)
271+
.await().atMost(Duration.ofSeconds(5));
272+
}).isNotInstanceOf(IllegalStateException.class)
273+
.cause()
274+
.hasMessageContaining("boom");
237275
}
238276

239277
@Test

0 commit comments

Comments
 (0)