in brooklyn-server/utils/common/src/main/java/org/apache/brooklyn/util/repeat/Repeater.java [309:377]
public ReferenceWithError<Boolean> runKeepingError() {
Preconditions.checkState(body != null, "repeat() method has not been called to set the body");
Preconditions.checkState(exitCondition != null, "until() method has not been called to set the exit condition");
Preconditions.checkState(delayOnIteration != null, "every() method (or other delaySupplier() / backoff() method) has not been called to set the loop delay");
Throwable lastError = null;
int iterations = 0;
CountdownTimer timer = timeLimit!=null ? CountdownTimer.newInstanceStarted(timeLimit) : CountdownTimer.newInstancePaused(Duration.PRACTICALLY_FOREVER);
while (true) {
Duration delayThisIteration = delayOnIteration.apply(iterations);
iterations++;
try {
body.call();
} catch (Exception e) {
log.warn(description, e);
if (rethrowExceptionImmediately) throw Exceptions.propagate(e);
}
boolean done = false;
try {
lastError = null;
done = exitCondition.call();
} catch (Exception e) {
if (log.isDebugEnabled()) log.debug(description, e);
lastError = e;
if (rethrowExceptionImmediately) throw Exceptions.propagate(e);
}
if (done) {
if (log.isDebugEnabled()) log.debug("{}: condition satisfied", description);
return ReferenceWithError.newInstanceWithoutError(true);
} else {
if (log.isDebugEnabled()) {
String msg = String.format("%s: unsatisfied during iteration %s %s", description, iterations,
(iterationLimit > 0 ? "(max "+iterationLimit+" attempts)" : "") +
(timer.isRunning() ? "("+Time.makeTimeStringRounded(timer.getDurationRemaining())+" remaining)" : ""));
if (iterations == 1) {
log.debug(msg);
} else {
log.trace(msg);
}
}
}
if (iterationLimit > 0 && iterations >= iterationLimit) {
if (log.isDebugEnabled()) log.debug("{}: condition not satisfied and exceeded iteration limit", description);
if (rethrowException && lastError != null) {
log.warn("{}: error caught checking condition (rethrowing): {}", description, lastError.getMessage());
throw Exceptions.propagate(lastError);
}
if (warnOnUnRethrownException && lastError != null)
log.warn("{}: error caught checking condition: {}", description, lastError.getMessage());
return ReferenceWithError.newInstanceMaskingError(false, lastError);
}
if (timer.isExpired()) {
if (log.isDebugEnabled()) log.debug("{}: condition not satisfied, with {} elapsed (limit {})",
new Object[] { description, Time.makeTimeStringRounded(timer.getDurationElapsed()), Time.makeTimeStringRounded(timeLimit) });
if (rethrowException && lastError != null) {
log.error("{}: error caught checking condition: {}", description, lastError.getMessage());
throw Exceptions.propagate(lastError);
}
return ReferenceWithError.newInstanceMaskingError(false, lastError);
}
Time.sleep(delayThisIteration);
}
}