package core.aws.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.function.Predicate;
/**
* @author neo
*/
public class Runner<T> {
private final Logger logger = LoggerFactory.getLogger(Runner.class);
int maxAttempts;
Duration retryInterval;
Predicate<Exception> predicate;
public T run(Callable<T> task) throws Exception {
int attempts = 0;
while (true) {
try {
attempts++;
return task.call();
} catch (Exception e) {
if (attempts >= maxAttempts || !predicate.test(e)) throw e;
logger.warn("failed to execute aws operation, retry soon", e);
Threads.sleepRoughly(retryInterval.multipliedBy((long) (Math.pow(2, attempts - 1))));
}
}
}
public Runner<T> maxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
return this;
}
public Runner<T> retryInterval(Duration retryInterval) {
this.retryInterval = retryInterval;
return this;
}
public Runner<T> retryOn(Predicate<Exception> predicate) {
this.predicate = predicate;
return this;
}
}