Skip to content

Commit

Permalink
Fix asynchronous @BeforeRetry
Browse files Browse the repository at this point in the history
The async implementation of retry had a bug in that it attempted to call
the before retry action even before the initial attempt. This is wrong,
plus it leads to an exception in the constructor of `FailureContext`.
This commit fixes that bug and adds missing tests.
  • Loading branch information
Ladicek committed Oct 30, 2024
1 parent d857efe commit 9e57a27
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private CompletionStage<V> afterDelay(InvocationContext<CompletionStage<V>> ctx,
}
}

if (beforeRetry != null) {
if (beforeRetry != null && attempt > 0) {
try {
beforeRetry.accept(new FailureContext(lastFailure, ctx));
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.smallrye.faulttolerance.async.compstage.retry.beforeretry;

import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.concurrent.CompletableFuture.failedFuture;

import java.io.IOException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.atomic.AtomicInteger;

import jakarta.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.faulttolerance.Asynchronous;
import org.eclipse.microprofile.faulttolerance.Fallback;
import org.eclipse.microprofile.faulttolerance.Retry;

import io.smallrye.faulttolerance.api.BeforeRetry;

@ApplicationScoped
public class AsyncHelloService {
static final AtomicInteger COUNTER = new AtomicInteger(0);
static final AtomicInteger BEFORE_RETRY_COUNTER = new AtomicInteger(0);

@Asynchronous
@Retry(maxRetries = 2)
@BeforeRetry(methodName = "beforeRetry")
@Fallback(fallbackMethod = "fallback")
public CompletionStage<String> hello() {
COUNTER.incrementAndGet();
return failedFuture(new IOException("Simulated IO error"));
}

private void beforeRetry() {
BEFORE_RETRY_COUNTER.incrementAndGet();
}

private CompletionStage<String> fallback() {
return completedFuture("Fallback");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.smallrye.faulttolerance.async.compstage.retry.beforeretry;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.concurrent.ExecutionException;

import org.junit.jupiter.api.Test;

import io.smallrye.faulttolerance.util.FaultToleranceBasicTest;

@FaultToleranceBasicTest
public class AsynchronousCompletionStageRetryTest {
@Test
public void testAsyncBeforeRetry(AsyncHelloService helloService) throws InterruptedException, ExecutionException {
assertThat(helloService.hello().toCompletableFuture().get()).isEqualTo("Fallback");
assertThat(AsyncHelloService.COUNTER.get()).isEqualTo(3);
assertThat(AsyncHelloService.BEFORE_RETRY_COUNTER.get()).isEqualTo(2);
}
}

0 comments on commit 9e57a27

Please sign in to comment.