Backoff { @SuppressWarnings("checkstyle:designforextension") public void exponentialBackoff() throws InterruptedException { if (currentType != BackoffType.EXPONENTIAL) { reset(); } currentType = BackoffType.EXPONENTIAL; exponentialWaitFor *= EXPONENTIAL_BACKOFF_INC; if (exponentialWaitFor > EXPONENTIAL_BACKOFF_MAX) { exponentialWaitFor = EXPONENTIAL_BACKOFF_MAX; } metrics.sendExponentialBackoff.mark(); log.info("Exponential backoff for {} ms", exponentialWaitFor); sleeper.sleep(exponentialWaitFor); } Backoff(
            final Sleeper sleeper,
            final Logger log,
            final Metrics metrics); @SuppressWarnings("checkstyle:designforextension") void linearBackoff(); @SuppressWarnings("checkstyle:designforextension") void exponentialBackoff(); @SuppressWarnings("checkstyle:designforextension") void waitUntil(final long waitUntil); @SuppressWarnings("checkstyle:designforextension") void reset();  }
@Test public void should_backoff_exponentially() throws InterruptedException { Logger loggger = mock(Logger.class); Metrics metrics = new Metrics(); Sleeper sleeper = mock(Sleeper.class); Backoff b = new Backoff(sleeper, loggger, metrics); b.exponentialBackoff(); verify(sleeper).sleep(1000); b.exponentialBackoff(); verify(sleeper).sleep(2000); b.exponentialBackoff(); verify(sleeper).sleep(4000); b.exponentialBackoff(); verify(sleeper).sleep(8000); b.exponentialBackoff(); verify(sleeper).sleep(10000); b.exponentialBackoff(); verify(sleeper, times(2)).sleep(10000); }
@Test public void should_mark_metric_for_exponential_backoff() throws InterruptedException { Logger loggger = mock(Logger.class); Metrics metrics = new Metrics(); Sleeper sleeper = mock(Sleeper.class); Backoff b = new Backoff(sleeper, loggger, metrics); b.exponentialBackoff(); assertEquals(1, metrics.sendExponentialBackoff.getCount()); }