public static <E extends Exception> long waitFor(Configuration conf, long timeout, long interval,
    boolean failIfTimeout, Predicate<E> predicate) {
    long started = EnvironmentEdgeManager.currentTime();
    long adjustedTimeout = (long) (getWaitForRatio(conf) * timeout);
    long mustEnd = started + adjustedTimeout;
    long remainderWait;
    long sleepInterval;
    boolean eval;
    boolean interrupted = false;

    try {
      LOG.info(MessageFormat.format("Waiting up to [{0}] milli-secs(wait.for.ratio=[{1}])",
        adjustedTimeout, getWaitForRatio(conf)));
      while (
        !(eval = predicate.evaluate())
          && (remainderWait = mustEnd - EnvironmentEdgeManager.currentTime()) > 0
      ) {
        try {
          // handle tail case when remainder wait is less than one interval
          sleepInterval = Math.min(remainderWait, interval);
          Thread.sleep(sleepInterval);
        } catch (InterruptedException e) {
          eval = predicate.evaluate();
          interrupted = true;
          break;
        }
      }
      if (!eval) {
        if (interrupted) {
          LOG.warn(MessageFormat.format("Waiting interrupted after [{0}] msec",
            EnvironmentEdgeManager.currentTime() - started));
        } else if (failIfTimeout) {
          String msg = getExplanation(predicate);
          fail(MessageFormat.format("Waiting timed out after [{0}] msec", adjustedTimeout) + msg);
        } else {
          String msg = getExplanation(predicate);
          LOG.warn(
            MessageFormat.format("Waiting timed out after [{0}] msec", adjustedTimeout) + msg);
        }
      }
      return (eval || interrupted) ? (EnvironmentEdgeManager.currentTime() - started) : -1;
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }
Waits up to the duration equal to the specified timeout multiplied by the
{@link #getWaitForRatio(Configuration)} for the given {@link Predicate} to become
<code>true</code>, failing the test if the timeout is reached, the Predicate is still
<code>false</code> and failIfTimeout is set as <code>true</code>.
<p/>
@param conf          the configuration
@param timeout       the timeout in milliseconds to wait for the predicate.
@param interval      the interval in milliseconds to evaluate predicate.
@param failIfTimeout indicates if should fail current test case when times out.
@param predicate     the predicate to evaluate.
@return the effective wait, in milli-seconds until the predicate becomes <code>true</code> or
        wait is interrupted otherwise <code>-1</code> when times out
hbase-common/src/test/java/org/apache/hadoop/hbase/Waiter.java