public ReferenceWithError runKeepingError()

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);
        }
    }