All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.phantomthief.failover.util.FailoverUtils Maven / Gradle / Ivy
package com.github.phantomthief.failover.util;
import static com.google.common.base.Predicates.alwaysTrue;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import com.github.phantomthief.failover.Failover;
import com.github.phantomthief.failover.exception.NoAvailableResourceException;
import com.github.phantomthief.util.ThrowableConsumer;
import com.github.phantomthief.util.ThrowableFunction;
/**
* @author w.vela
*/
public class FailoverUtils {
private FailoverUtils() {
throw new UnsupportedOperationException();
}
public static R supplyWithRetry(int maxRetryTimes,
long sleepBetweenRetryMs, Failover failover, ThrowableFunction func)
throws X {
return supplyWithRetry(maxRetryTimes, sleepBetweenRetryMs, failover, func, alwaysTrue());
}
/**
* @param failChecker {@code true} if need retry, {@code false} means no need retry and mark success
*/
public static R supplyWithRetry(int maxRetryTimes,
long sleepBetweenRetryMs, Failover failover, ThrowableFunction func,
@Nonnull Predicate failChecker) throws X {
Set failed = new HashSet<>();
Throwable lastError = null;
for (int i = 0; i < maxRetryTimes; i++) {
T oneAvailable = failover.getOneAvailableExclude(failed);
if (oneAvailable != null) {
try {
R result = func.apply(oneAvailable);
failover.success(oneAvailable);
return result;
} catch (Throwable e) {
if (failChecker.test(e)) {
failover.fail(oneAvailable);
failed.add(oneAvailable);
if (sleepBetweenRetryMs > 0) {
sleepUninterruptibly(sleepBetweenRetryMs, MILLISECONDS);
}
lastError = e;
continue;
} else {
failover.success(oneAvailable);
throw e;
}
}
} else {
throw new NoAvailableResourceException();
}
}
throwIfUnchecked(lastError);
throw new RuntimeException(lastError);
}
public static R supply(Failover failover,
ThrowableFunction func, Predicate failChecker) throws X {
T oneAvailable = failover.getOneAvailable();
if (oneAvailable != null) {
try {
R result = func.apply(oneAvailable);
failover.success(oneAvailable);
return result;
} catch (Throwable e) {
if (failChecker == null || failChecker.test(e)) {
failover.fail(oneAvailable);
} else {
failover.success(oneAvailable);
}
throw e;
}
} else {
throw new NoAvailableResourceException();
}
}
public static void runWithRetry(int maxRetryTimes,
long sleepBetweenRetryMs, Failover failover, ThrowableConsumer func) throws X {
supplyWithRetry(maxRetryTimes, sleepBetweenRetryMs, failover, t -> {
func.accept(t);
return null;
}, alwaysTrue());
}
/**
* @param failChecker {@code true} if need retry, {@code false} means no need retry and mark success
*/
public static void runWithRetry(int maxRetryTimes,
long sleepBetweenRetryMs, Failover failover, ThrowableConsumer func,
@Nonnull Predicate failChecker) throws X {
supplyWithRetry(maxRetryTimes, sleepBetweenRetryMs, failover, t -> {
func.accept(t);
return null;
}, failChecker);
}
public static void run(Failover failover,
ThrowableConsumer func, Predicate failChecker) throws X {
supply(failover, t -> {
func.accept(t);
return null;
}, failChecker);
}
}