ZonkyApiTokenSupplier implements Supplier<ZonkyApiToken>,
        AutoCloseable { static Duration reloadAfter(final ZonkyApiToken token) { var now = DateUtil.offsetNow(); var expiresOn = token.getExpiresOn(); var halfLife = Duration.between(now, expiresOn) .abs() .dividedBy(2); if (halfLife.compareTo(ONE_HOUR) > 0) { return ONE_HOUR; } else { return halfLife; } } ZonkyApiTokenSupplier(final ApiProvider apis, final SecretProvider secrets); boolean isClosed(); @Override ZonkyApiToken get(); @Override void close();  }
@Test void reloadInterval() { var token = getTokenExpiringIn(Duration.ofMinutes(119)); assertThat(reloadAfter(token)).isBetween(Duration.ofMinutes(59), Duration.ofMinutes(60)); var token2 = getTokenExpiringIn(Duration.ofHours(2)); assertThat(reloadAfter(token2)).isEqualTo(Duration.ofHours(1)); var token3 = getTokenExpiringIn(Duration.ofMinutes(121)); assertThat(reloadAfter(token3)).isBetween(Duration.ofMinutes(60), Duration.ofMinutes(61)); }