private static <R> R exponentialBackOffRetry(long initialDelayMs,
                                               long backoffLimitMs,
                                               int maxAttempts,
                                               @NotNull ThrowingSupplier<? extends R> supplier,
                                               @NotNull Logger logger) throws Exception {
    long effectiveDelay = initialDelayMs;

    for (int i = 1; i <= maxAttempts; i++) {
      try {
        return supplier.get();
      }
      catch (Exception e) {
        if (i == maxAttempts) {
          logger.warn("Retry attempts limit exceeded, tried " + maxAttempts + " times. Cause: " + e.getMessage(), e);
          throw e;
        }
        logger.warn("Attempt " + i + " of " + maxAttempts + " failed, retrying in " + effectiveDelay + "ms. Cause: " + e.getMessage(), e);
        effectiveDelay = exponentialBackOff(effectiveDelay, backoffLimitMs);
      }
    }
    throw new RuntimeException("Should not be reached");
  }
private static <R> R exponentialBackOffRetry(long initialDelayMs,
                                               long backoffLimitMs,
                                               int maxAttempts,
                                               @NotNull ThrowingSupplier<? extends R> supplier,
                                               @NotNull Logger logger)