Skip to content

Commit

Permalink
Support cancel feature for AsyncFeign
Browse files Browse the repository at this point in the history
  • Loading branch information
wplong11 committed Oct 22, 2022
1 parent ca761ae commit 7e00da1
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 6 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/feign/AsynchronousMethodHandler.java
Expand Up @@ -93,7 +93,7 @@ private CompletableFuture<Object> executeAndDecode(RequestTemplate template,
executeAndDecode(template, options)
.whenComplete((response, throwable) -> {
if (throwable != null) {
if (shouldRetry(retryer, throwable, resultFuture)) {
if (!resultFuture.isDone() && shouldRetry(retryer, throwable, resultFuture)) {
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
Expand Down
52 changes: 52 additions & 0 deletions core/src/test/java/feign/AsyncFeignTest.java
Expand Up @@ -48,16 +48,21 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okio.Buffer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.rules.ExpectedException;

public class AsyncFeignTest {
Expand Down Expand Up @@ -656,6 +661,53 @@ public void whenReturnTypeIsResponseNoErrorHandling() throws Throwable {
execs.shutdown();
}

@ParameterizedTest
@ValueSource(ints = {1}) // TODO: Modify it to work even if it is more than 2 tries
public void cancelRetry(final int expectedTryCount) throws Throwable {
// Arrange
final CompletableFuture<Boolean> maximumTryCompleted = new CompletableFuture<>();
final AtomicInteger actualTryCount = new AtomicInteger();
final AtomicBoolean isCancelled = new AtomicBoolean(true);

final int RUNNING_TIME_MILLIS = 100;
final ExecutorService execs = Executors.newSingleThreadExecutor();
final AsyncClient<Void> clientMock = (request, options, requestContext) ->
CompletableFuture.supplyAsync(() -> {
final int tryCount = actualTryCount.addAndGet(1);
if (tryCount < expectedTryCount) {
throw new CompletionException(new IOException());
}

if (tryCount > expectedTryCount) {
isCancelled.set(false);
throw new CompletionException(new IOException());
}

maximumTryCompleted.complete(true);
try {
Thread.sleep(RUNNING_TIME_MILLIS);
throw new IOException();
} catch (Throwable e) {
throw new CompletionException(e);
}
}, execs);
final TestInterfaceAsync sut = AsyncFeign.<Void>builder()
.client(clientMock)
.retryer(new Retryer.Default(0, Long.MAX_VALUE, expectedTryCount * 2))
.target(TestInterfaceAsync.class, "http://localhost:" + server.getPort());

// Act
final CompletableFuture<String> actual = sut.post();
maximumTryCompleted.join();
actual.cancel(true);
Thread.sleep(RUNNING_TIME_MILLIS * 5);

// Assert
assertThat(actualTryCount.get()).isEqualTo(expectedTryCount);
assertThat(isCancelled.get()).isTrue();
execs.shutdown();
}

private static class MockRetryer implements Retryer {

boolean tripped;
Expand Down
22 changes: 17 additions & 5 deletions pom.xml
Expand Up @@ -85,7 +85,7 @@
<bouncy.version>1.70</bouncy.version>
<json.version>20220924</json.version>

<junit.version>4.13.2</junit.version>
<junit.version>5.9.1</junit.version>
<jackson.version>2.14.0-rc2</jackson.version>
<jackson-databind.version>2.14.0-rc2</jackson-databind.version>
<assertj.version>3.23.1</assertj.version>
Expand Down Expand Up @@ -292,8 +292,14 @@
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.version}</version>
</dependency>

Expand Down Expand Up @@ -394,8 +400,14 @@

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>

Expand Down

0 comments on commit 7e00da1

Please sign in to comment.