@VisibleForTesting
  static long getRetryDelayInMs(long initDelayMs, int attemptId) {
    // TODO: Just exponential backoff by factor 2 for now. Can add other retry polices as needed.
    // The attemptId starts from 1, so minus one as the exponent.
    double minDelayMs = initDelayMs * Math.pow(RETRY_DELAY_SCALE_FACTOR, attemptId - 1);
    double maxDelayMs = minDelayMs * RETRY_DELAY_SCALE_FACTOR;
    if (maxDelayMs > minDelayMs) {
      return ThreadLocalRandom.current().nextLong((long) minDelayMs, (long) maxDelayMs);
    }
    return (long) minDelayMs;
  }
@Test
  public void testGetRetryDelayInMs() {
    assertEquals(RebalanceChecker.getRetryDelayInMs(0, 1), 0);
    assertEquals(RebalanceChecker.getRetryDelayInMs(0, 2), 0);
    assertEquals(RebalanceChecker.getRetryDelayInMs(0, 3), 0);

    for (long initDelayMs : new long[]{1, 30000, 3600000}) {
      long delayMs = RebalanceChecker.getRetryDelayInMs(initDelayMs, 1);
      assertTrue(delayMs >= initDelayMs && delayMs < initDelayMs * 2);
      delayMs = RebalanceChecker.getRetryDelayInMs(initDelayMs, 2);
      assertTrue(delayMs >= initDelayMs * 2 && delayMs < initDelayMs * 4);
      delayMs = RebalanceChecker.getRetryDelayInMs(initDelayMs, 3);
      assertTrue(delayMs >= initDelayMs * 4 && delayMs < initDelayMs * 8);
    }
  }