BAEL-7001: fixed formatting

This commit is contained in:
emanueltrandafir1993 2023-10-23 18:07:43 +02:00
parent 06943519f8
commit 210eaf2c0b
2 changed files with 139 additions and 137 deletions

View File

@ -5,59 +5,59 @@ import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class RetryCompletableFuture { public class RetryCompletableFuture {
public static <T> CompletableFuture<T> retryTask(Supplier<T> supplier, int maxRetries) { public static <T> CompletableFuture<T> retryTask(Supplier<T> supplier, int maxRetries) {
Supplier<T> retryableSupplier = retryFunction(supplier, maxRetries); Supplier<T> retryableSupplier = retryFunction(supplier, maxRetries);
return CompletableFuture.supplyAsync(retryableSupplier); return CompletableFuture.supplyAsync(retryableSupplier);
} }
static <T> Supplier<T> retryFunction(Supplier<T> supplier, int maxRetries) { static <T> Supplier<T> retryFunction(Supplier<T> supplier, int maxRetries) {
return () -> { return () -> {
int retries = 0; int retries = 0;
while (retries < maxRetries) { while (retries < maxRetries) {
try { try {
return supplier.get(); return supplier.get();
} catch (Exception e) { } catch (Exception e) {
retries++; retries++;
} }
} }
throw new IllegalStateException(String.format("Task failed after %s attempts", maxRetries)); throw new IllegalStateException(String.format("Task failed after %s attempts", maxRetries));
}; };
} }
public static <T> CompletableFuture<T> retryUnsafe(Supplier<T> supplier, int maxRetries) { public static <T> CompletableFuture<T> retryUnsafe(Supplier<T> supplier, int maxRetries) {
CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier); CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier);
sleep(100l); sleep(100l);
for (int i = 0; i < maxRetries; i++) { for (int i = 0; i < maxRetries; i++) {
cf = cf.exceptionally(__ -> supplier.get()); cf = cf.exceptionally(__ -> supplier.get());
} }
return cf; return cf;
} }
public static <T> CompletableFuture<T> retryNesting(Supplier<T> supplier, int maxRetries) { public static <T> CompletableFuture<T> retryNesting(Supplier<T> supplier, int maxRetries) {
CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier); CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier);
sleep(100); sleep(100);
for (int i = 0; i < maxRetries; i++) { for (int i = 0; i < maxRetries; i++) {
cf = cf.thenApply(CompletableFuture::completedFuture) cf = cf.thenApply(CompletableFuture::completedFuture)
.exceptionally(__ -> CompletableFuture.supplyAsync(supplier)) .exceptionally(__ -> CompletableFuture.supplyAsync(supplier))
.thenCompose(Function.identity()); .thenCompose(Function.identity());
} }
return cf; return cf;
} }
public static <T> CompletableFuture<T> retryExceptionallyAsync(Supplier<T> supplier, int maxRetries) { public static <T> CompletableFuture<T> retryExceptionallyAsync(Supplier<T> supplier, int maxRetries) {
CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier); CompletableFuture<T> cf = CompletableFuture.supplyAsync(supplier);
sleep(100); sleep(100);
for (int i = 0; i < maxRetries; i++) { for (int i = 0; i < maxRetries; i++) {
cf = cf.exceptionallyAsync(__ -> supplier.get()); cf = cf.exceptionallyAsync(__ -> supplier.get());
} }
return cf; return cf;
} }
private static void sleep(long millis) { private static void sleep(long millis) {
try { try {
Thread.sleep(millis); Thread.sleep(millis);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
} }

View File

@ -1,125 +1,127 @@
package com.baeldung.concurrent.completablefuture.retry; package com.baeldung.concurrent.completablefuture.retry;
import org.junit.jupiter.api.BeforeEach; import static com.baeldung.concurrent.completablefuture.retry.RetryCompletableFuture.retryExceptionallyAsync;
import org.junit.jupiter.api.Test; import static com.baeldung.concurrent.completablefuture.retry.RetryCompletableFuture.retryNesting;
import static com.baeldung.concurrent.completablefuture.retry.RetryCompletableFuture.retryTask;
import static com.baeldung.concurrent.completablefuture.retry.RetryCompletableFuture.retryUnsafe;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier; import java.util.function.Supplier;
import static com.baeldung.concurrent.completablefuture.retry.RetryCompletableFuture.*; import org.junit.jupiter.api.BeforeEach;
import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class RetryCompletableFutureUnitTest { class RetryCompletableFutureUnitTest {
private AtomicInteger retriesCounter = new AtomicInteger(0); private AtomicInteger retriesCounter = new AtomicInteger(0);
@BeforeEach @BeforeEach
void beforeEach() { void beforeEach() {
retriesCounter.set(0); retriesCounter.set(0);
} }
@Test @Test
void whenRetryingTask_thenReturnsCorrectlyAfterFourInvocations() { void whenRetryingTask_thenReturnsCorrectlyAfterFourInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryTask(codeToRun, 10); CompletableFuture<Integer> result = retryTask(codeToRun, 10);
assertThat(result.join()) assertThat(result.join())
.isEqualTo(100); .isEqualTo(100);
assertThat(retriesCounter) assertThat(retriesCounter)
.hasValue(4); .hasValue(4);
} }
@Test @Test
void whenRetryingTask_thenThrowsExceptionAfterThreeInvocations() { void whenRetryingTask_thenThrowsExceptionAfterThreeInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryTask(codeToRun, 3); CompletableFuture<Integer> result = retryTask(codeToRun, 3);
assertThatThrownBy(result::join) assertThatThrownBy(result::join).isInstanceOf(CompletionException.class)
.isInstanceOf(CompletionException.class) .hasMessageContaining("IllegalStateException: Task failed after 3 attempts");
.hasMessageContaining("IllegalStateException: Task failed after 3 attempts"); }
}
@Test @Test
void whenRetryingExceptionally_thenReturnsCorrectlyAfterFourInvocations() { void whenRetryingExceptionally_thenReturnsCorrectlyAfterFourInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryUnsafe(codeToRun, 10); CompletableFuture<Integer> result = retryUnsafe(codeToRun, 10);
assertThat(result.join()) assertThat(result.join())
.isEqualTo(100); .isEqualTo(100);
assertThat(retriesCounter) assertThat(retriesCounter)
.hasValue(4); .hasValue(4);
} }
@Test @Test
void whenRetryingExceptionally_thenThrowsExceptionAfterThreeInvocations() { void whenRetryingExceptionally_thenThrowsExceptionAfterThreeInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryUnsafe(codeToRun, 3); CompletableFuture<Integer> result = retryUnsafe(codeToRun, 3);
assertThatThrownBy(result::join) assertThatThrownBy(result::join)
.isInstanceOf(CompletionException.class) .isInstanceOf(CompletionException.class)
.hasMessageContaining("RuntimeException: task failed for 3 time(s)"); .hasMessageContaining("RuntimeException: task failed for 3 time(s)");
} }
@Test @Test
void whenRetryingExceptionallyAsync_thenReturnsCorrectlyAfterFourInvocations() { void whenRetryingExceptionallyAsync_thenReturnsCorrectlyAfterFourInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryExceptionallyAsync(codeToRun, 10); CompletableFuture<Integer> result = retryExceptionallyAsync(codeToRun, 10);
assertThat(result.join()) assertThat(result.join())
.isEqualTo(100); .isEqualTo(100);
assertThat(retriesCounter) assertThat(retriesCounter)
.hasValue(4); .hasValue(4);
} }
@Test @Test
void whenRetryingExceptionallyAsync_thenThrowsExceptionAfterThreeInvocations() { void whenRetryingExceptionallyAsync_thenThrowsExceptionAfterThreeInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryExceptionallyAsync(codeToRun, 3); CompletableFuture<Integer> result = retryExceptionallyAsync(codeToRun, 3);
assertThatThrownBy(result::join) assertThatThrownBy(result::join)
.isInstanceOf(CompletionException.class) .isInstanceOf(CompletionException.class)
.hasMessageContaining("RuntimeException: task failed for 3 time(s)"); .hasMessageContaining("RuntimeException: task failed for 3 time(s)");
} }
@Test @Test
void whenRetryingNesting_thenReturnsCorrectlyAfterFourInvocations() { void whenRetryingNesting_thenReturnsCorrectlyAfterFourInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryNesting(codeToRun, 10); CompletableFuture<Integer> result = retryNesting(codeToRun, 10);
assertThat(result.join()) assertThat(result.join())
.isEqualTo(100); .isEqualTo(100);
assertThat(retriesCounter) assertThat(retriesCounter)
.hasValue(4); .hasValue(4);
} }
@Test @Test
void whenRetryingNesting_thenThrowsExceptionAfterThreeInvocations() { void whenRetryingNesting_thenThrowsExceptionAfterThreeInvocations() {
Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100); Supplier<Integer> codeToRun = () -> failFourTimesThenReturn(100);
CompletableFuture<Integer> result = retryNesting(codeToRun, 3); CompletableFuture<Integer> result = retryNesting(codeToRun, 3);
assertThatThrownBy(result::join) assertThatThrownBy(result::join)
.isInstanceOf(CompletionException.class) .isInstanceOf(CompletionException.class)
.hasMessageContaining("RuntimeException: task failed for 3 time(s)"); .hasMessageContaining("RuntimeException: task failed for 3 time(s)");
} }
int failFourTimesThenReturn(int returnValue) { int failFourTimesThenReturn(int returnValue) {
int retryNr = retriesCounter.get(); int retryNr = retriesCounter.get();
System.out.println(String.format("invocation: %s, thread: %s", retryNr, Thread.currentThread().getName())); System.out.println(String.format("invocation: %s, thread: %s", retryNr, Thread.currentThread().getName()));
if (retryNr < 4) { if (retryNr < 4) {
retriesCounter.set(retryNr + 1); retriesCounter.set(retryNr + 1);
throw new RuntimeException(String.format("task failed for %s time(s)", retryNr)); throw new RuntimeException(String.format("task failed for %s time(s)", retryNr));
} }
return returnValue; return returnValue;
} }
} }