package com.appmetr.hercules.failover;
import me.prettyprint.hector.api.exceptions.HTimedOutException;
import me.prettyprint.hector.api.exceptions.HUnavailableException;
import me.prettyprint.hector.api.exceptions.HectorException;
import org.slf4j.Logger;
public class FailoverQueryProcessor {
public static <T> T process(FailoverConf conf, Logger logger, FailoverQuery<T> query) throws HectorException {
if (conf.getMaxRetries() == 0) {
throw new IllegalArgumentException("Invalid retries count: " + conf.getMaxRetries());
}
int retryCount = 0;
int currSleepBetweenRetries = Math.min(conf.getStartSleepBetweenRetriesMs(), conf.getMaxSleepBetweenRetriesMs());
while (true) {
HectorException exception;
try {
return query.query();
} catch (HTimedOutException e) {
exception = e;
} catch (HUnavailableException e) {
exception = e;
}
retryCount++;
if (conf.getMaxRetries() > 0 && retryCount >= conf.getMaxRetries()) {
throw exception;
}
if (logger != null) {
logger.error(String.format("Failovering: retries count - %1$s, sleep between - %2$s\n", retryCount, currSleepBetweenRetries), exception);
}
try {
Thread.sleep(currSleepBetweenRetries);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
currSleepBetweenRetries = Math.min((int) (currSleepBetweenRetries * conf.getSleepBetweenRetriesIncreaseRatio() + 0.5), conf.getMaxSleepBetweenRetriesMs());
}
}
public static void process(FailoverConf conf, Logger logger, final VoidFailoverQuery query) throws HectorException {
process(conf, logger, new FailoverQuery<Void>() {
@Override public Void query() {
query.query();
return null;
}
});
}
}