public boolean run() throws E {
    for (int i = 0; i < maximumRetries; i++) {
      try {
        // sleep between attempts, but not on the first attempt
        if (i > 0 && sleepMilliseconds >= 0) {
          Thread.sleep(sleepMilliseconds);
        }

        // Do we need to continue?
        if (action.run()) {
          return true;
        }

      } catch (InterruptedException ex) {
        // Restore the interrupted status
        Thread.currentThread().interrupt();
        return false;

      } catch (Exception ex) {
        // if this is the last iteration, no more retries
        if (i + 1 == maximumRetries || !retryOnException.test(ex)) {
          throw ex;
        }
      }
    }
    // we did not complete
    return false;
  }
Run the action until it runs successfully, to a {@link #maximumRetries(int) maximum number of
retries} (default: 5). If an exception occurs then the action will be retried providing {@link
#retryOnException(Predicate) the exception is retryable}.

@return true if the action was run successfully, or {@code false} if the action was unable to
    complete
@throws E exception thrown during the action
jib-core/src/main/java/com/google/cloud/tools/jib/cache/Retry.java