package com.nurkiewicz.asyncretry;
import com.nurkiewicz.asyncretry.function.RetryCallable;
import com.nurkiewicz.asyncretry.function.RetryRunnable;
import com.nurkiewicz.asyncretry.policy.RetryPolicy;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
/**
* Singleton instance of {@link RetryExecutor} that executes tasks in the same thread and without retry.
* Useful for testing or when no-op implementation of {@link RetryExecutor} is needed.
* This implementation, while implements the API, runs all tasks synchronously so that returned futures are already completed.
* Exceptions are not thrown but wrapped in Future as well.
* @since 0.0.6
*/
public enum SyncRetryExecutor implements RetryExecutor {
INSTANCE;
private static final AsyncRetryContext RETRY_CONTEXT = new AsyncRetryContext(RetryPolicy.DEFAULT);
@Override
public CompletableFuture<Void> doWithRetry(RetryRunnable action) {
try {
action.run(RETRY_CONTEXT);
return CompletableFuture.completedFuture(null);
} catch (Exception e) {
return failedFuture(e);
}
}
@Override
public <V> CompletableFuture<V> getWithRetry(Callable<V> task) {
try {
return CompletableFuture.completedFuture(task.call());
} catch (Exception e) {
return failedFuture(e);
}
}
@Override
public <V> CompletableFuture<V> getWithRetry(RetryCallable<V> task) {
try {
return CompletableFuture.completedFuture(task.call(RETRY_CONTEXT));
} catch (Exception e) {
return failedFuture(e);
}
}
@Override
public <V> CompletableFuture<V> getFutureWithRetry(RetryCallable<CompletableFuture<V>> task) {
try {
return task.call(RETRY_CONTEXT);
} catch (Exception e) {
return failedFuture(e);
}
}
private static <T> CompletableFuture<T> failedFuture(Exception e) {
final CompletableFuture<T> promise = new CompletableFuture<>();
promise.completeExceptionally(e);
return promise;
}
}