common/src/main/java/org/jboss/pnc/common/monitor/PullingMonitor.java
public RunningTask monitor(Runnable onMonitorComplete, Consumer<Exception> onMonitorError, Supplier<Boolean> condition, int checkInterval, int timeout, TimeUnit timeUnit) {

        ObjectWrapper<RunningTask> runningTaskReference = new ObjectWrapper<>();
        Runnable monitor = () -> {
            RunningTask runningTask = runningTaskReference.get();

            if (runningTask == null) {
                /* There might be a situation where this runnable is called before runningTaskReference is set with the
                 * running task since this runnable is scheduled to run before runningTaskReference is set. In that
                 * case, we just skip this runnable and re-run on the next scheduled interval with the assumption that
                 * runningTaskReference will be set before the next re-run
                 */
                log.debug("runningTask not set yet inside the 'monitor' runnable! Skipping!");
                return;
            }
            try {
                // Check if given condition is satisfied
                if (condition.get()) {
                    runningTasks.remove(runningTask);
                    runningTask.cancel();
                    onMonitorComplete.run();
                }
            } catch (Exception e) {
                log.error("Exception in monitor runnable", e);
                runningTasks.remove(runningTask);
                runningTask.cancel();
                onMonitorError.accept(e);
            }
        };
        ScheduledFuture<?> future = executorService.scheduleWithFixedDelay(monitor, 0L, checkInterval, timeUnit);
        Consumer<RunningTask> onTimeout = (runningTask) -> {
            runningTasks.remove(runningTask);
            onMonitorError.accept(new MonitorException("Service was not ready in: " + timeout + " " + timeUnit.toString()));
        }
public RunningTask monitor(Runnable onMonitorComplete, Consumer<Exception> onMonitorError, Supplier<Boolean> condition, int checkInterval, int timeout, TimeUnit timeUnit) {

        ObjectWrapper<RunningTask> runningTaskReference = new ObjectWrapper<>();
        Runnable monitor = () -> {
            RunningTask runningTask = runningTaskReference.get();

            if (runningTask == null) {
                /* There might be a situation where this runnable is called before runningTaskReference is set with the
                 * running task since this runnable is scheduled to run before runningTaskReference is set. In that
                 * case, we just skip this runnable and re-run on the next scheduled interval with the assumption that
                 * runningTaskReference will be set before the next re-run
                 */
                log.debug("runningTask not set yet inside the 'monitor' runnable! Skipping!");
                return;
            }
            try {
                // Check if given condition is satisfied
                if (condition.get()) {
                    runningTasks.remove(runningTask);
                    runningTask.cancel();
                    onMonitorComplete.run();
                }
            } catch (Exception e) {
                log.error("Exception in monitor runnable", e);
                runningTasks.remove(runningTask);
                runningTask.cancel();
                onMonitorError.accept(e);
            }
        };
        ScheduledFuture<?> future = executorService.scheduleWithFixedDelay(monitor, 0L, checkInterval, timeUnit);
        Consumer<RunningTask> onTimeout = (runningTask) -> {
            runningTasks.remove(runningTask);
            onMonitorError.accept(new MonitorException("Service was not ready in: " + timeout + " " + timeUnit.toString()));
        }
Periodically checks the condition and calls onMonitorComplete when it returns true.
If timeout is reached onMonitorError is called.

@param onMonitorComplete
@param onMonitorError
@param condition
@param checkInterval
@param timeout
@param timeUnit Unit used for checkInterval and timeout