public static <T> T waitFor(MasterProcedureEnv env, long waitTime, long waitingTimeForEvents,
    String purpose, Predicate<T> predicate) throws IOException {
    long done = EnvironmentEdgeManager.currentTime() + waitTime;
    if (done <= 0) {
      // long overflow, usually this means we pass Long.MAX_VALUE as waitTime
      done = Long.MAX_VALUE;
    }
    boolean logged = false;
    do {
      T result = predicate.evaluate();
      if (result != null && !result.equals(Boolean.FALSE)) {
        return result;
      }
      try {
        Thread.sleep(waitingTimeForEvents);
      } catch (InterruptedException e) {
        LOG.warn("Interrupted while sleeping, waiting on " + purpose);
        throw (InterruptedIOException) new InterruptedIOException().initCause(e);
      }
      if (LOG.isTraceEnabled()) {
        LOG.trace("waitFor " + purpose);
      } else {
        if (!logged) LOG.debug("waitFor " + purpose);
      }
      logged = true;
    } while (EnvironmentEdgeManager.currentTime() < done && env.isRunning());

    throw new TimeoutIOException("Timed out while waiting on " + purpose);
  }
Helper to synchronously wait on conditions. This will be removed in the future (mainly when the
AssignmentManager will be replaced with a Procedure version) by using ProcedureYieldException,
and the queue will handle waiting and scheduling based on events.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java