Skip to content

Instantly share code, notes, and snippets.

@bassemZohdy
Created September 4, 2015 16:11
Show Gist options
  • Save bassemZohdy/3aa7b36d7525ab12bef7 to your computer and use it in GitHub Desktop.
Save bassemZohdy/3aa7b36d7525ab12bef7 to your computer and use it in GitHub Desktop.
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
public class RetrySupplyAsync<T> implements Supplier<CompletableFuture<T>> {
private final Supplier<T> supplier;
private final int tries;
private final T defaultValue;
private final long sleep;
private final Class<? extends Throwable> throwableClass;
private final Executor executor;
// Constructors
private RetrySupplyAsync(Supplier<T> supplier, int tries, T defaultValue,
long sleep, Class<? extends Throwable> throwableClass,
Executor executor) {
this.supplier = supplier;
this.tries = tries;
this.defaultValue = defaultValue;
this.sleep = sleep;
this.throwableClass = throwableClass;
this.executor = executor;
}
private RetrySupplyAsync(Supplier<T> supplier, int tries, T defaultValue,
long sleep, Class<? extends Throwable> throwableClass) {
this(supplier, tries, defaultValue, sleep, throwableClass, null);
}
private RetrySupplyAsync(Supplier<T> supplier, int tries, T defaultValue,
long sleep, Executor executor) {
this(supplier, tries, defaultValue, sleep, Throwable.class, executor);
}
private RetrySupplyAsync(Supplier<T> supplier, int tries, T defaultValue,
long sleep) {
this(supplier, tries, defaultValue, sleep, Throwable.class, null);
}
private RetrySupplyAsync(Supplier<T> supplier, int tries, T defaultValue) {
this(supplier, tries, defaultValue, 1000, Throwable.class, null);
}
// static methods
public static <T> RetrySupplyAsync<T> of(Supplier<T> supplier, int tries,
T defaultValue) {
return new RetrySupplyAsync<T>(supplier, tries, defaultValue);
}
public static <T> RetrySupplyAsync<T> of(Supplier<T> supplier, int tries,
T defaultValue, long sleep) {
return new RetrySupplyAsync<T>(supplier, tries, defaultValue, sleep);
}
public static <T> RetrySupplyAsync<T> of(Supplier<T> supplier, int tries,
T defaultValue, long sleep, Executor executor) {
return new RetrySupplyAsync<T>(supplier, tries, defaultValue, sleep,
executor);
}
public static <T> RetrySupplyAsync<T> of(Supplier<T> supplier, int tries,
T defaultValue, long sleep,
Class<? extends Throwable> throwableClass) {
return new RetrySupplyAsync<T>(supplier, tries, defaultValue, sleep,
throwableClass);
}
public static <T> RetrySupplyAsync<T> of(Supplier<T> supplier, int tries,
T defaultValue, long sleep,
Class<? extends Throwable> throwableClass, Executor executor) {
return new RetrySupplyAsync<T>(supplier, tries, defaultValue, sleep,
throwableClass, executor);
}
@Override
public CompletableFuture<T> get() {
if (executor == null)
return async();
else
return async(executor);
}
private CompletableFuture<T> async() {
return CompletableFuture.supplyAsync(supplier).handleAsync(
(m, t) -> {
if (t == null)
return m;
else {
try {
if (tries <= 1 || !throwableClass.isInstance(t))
return defaultValue;
Thread.sleep(sleep);
return RetrySupplyAsync
.of(supplier, tries - 1, defaultValue,
sleep, throwableClass).get().get();
} catch (Throwable th) {
return defaultValue;
}
}
});
}
private CompletableFuture<T> async(Executor executor) {
return CompletableFuture.supplyAsync(supplier, executor).handleAsync(
(m, t) -> {
if (t == null)
return m;
else {
try {
if (tries <= 1 || !throwableClass.isInstance(t))
return defaultValue;
Thread.sleep(sleep);
return RetrySupplyAsync
.of(supplier, tries - 1, defaultValue,
sleep, throwableClass, executor)
.get().get();
} catch (Throwable th) {
return defaultValue;
}
}
}, executor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment