return execute(PartitionContextBuilder.empty(), retry, callback);
}
@Override
public <R> R execute(PartitionContext partitionContext, RetryPolicy retry, ServiceCallback<S, R> callback) {
Stopwatch sw = new Stopwatch(_ticker).start();
int numAttempts = 0;
Exception lastException = null;
do {
Iterable<ServiceEndPoint> allEndPoints = getAllEndPoints();
if (Iterables.isEmpty(allEndPoints)) {
throw (lastException == null)
? new NoAvailableHostsException()
: new NoAvailableHostsException(lastException);
}
Iterable<ServiceEndPoint> validEndPoints = getValidEndPoints(allEndPoints);
if (Iterables.isEmpty(validEndPoints)) {
throw (lastException == null)
? new OnlyBadHostsException()
: new OnlyBadHostsException(lastException);
}
ServiceEndPoint endPoint = chooseEndPoint(validEndPoints, partitionContext);
if (endPoint == null) {
throw (lastException == null)
? new NoSuitableHostsException()
: new NoSuitableHostsException(lastException);
}
try {
R result = executeOnEndPoint(endPoint, callback);
_numExecuteSuccesses.mark();
return result;
} catch (Exception e) {
_numExecuteAttemptFailures.mark();
// Don't retry if exception is too severe.
if (!isRetriableException(e)) {
throw Throwables.propagate(e);
}
LOG.info("Retriable exception from end point id: {}, {}", endPoint.getId(), e.toString());
LOG.debug("Exception", e);
lastException = e;
}
} while (retry.allowRetry(++numAttempts, sw.elapsedMillis()));
throw new MaxRetriesException(lastException);
}