public BackOffTimer(ScheduledExecutorService scheduler) {
        this.scheduler = scheduler;
    }
@Test
    public void testBackOffTimer() throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicInteger counter = new AtomicInteger();
        final ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
        final BackOff backOff = BackOff.builder().delay(100).build();
        final BackOffTimer timer = new BackOffTimer(executor);
        final AtomicLong first = new AtomicLong();

        BackOffTimer.Task task = timer.schedule(
                backOff,
                context -> {
                    assertEquals(counter.incrementAndGet(), context.getCurrentAttempts());
                    assertEquals(100, context.getCurrentDelay());
                    assertEquals(100L * counter.get(), context.getCurrentElapsedTime());
                    if (first.get() == 0) {
                        first.set(context.getFirstAttemptTime());
                    } else {
                        assertEquals(first.get(), context.getFirstAttemptTime());
                    }

                    return counter.get() < 5;
                });

        task.whenComplete(
                (context, throwable) -> {
                    assertEquals(5, counter.get());
                    latch.countDown();
                });

        latch.await(5, TimeUnit.SECONDS);
        executor.shutdownNow();
    }