ReloadableImpl extends AbstractReloadableImpl<T> { @Override public Either<Throwable, T> get() { if (needsReload()) { synchronized (this) { if (needsReload()) { logger.trace("Reloading {}.", this); try { var v = getOperation().apply(value.get()); processRetrievedValue(v, value::set); return Either.right(v); } catch (Exception ex) { return Either.left(ex); } } } } logger.trace("Not reloading {}.", this); return Either.right(value.get()); } ReloadableImpl(final Supplier<T> supplier, final UnaryOperator<T> reloader,
            final Consumer<T> runWhenReloaded, final Set<ReloadListener<T>> listeners);  ReloadableImpl(final Supplier<T> supplier, final UnaryOperator<T> reloader,
            final Consumer<T> runWhenReloaded, final Set<ReloadListener<T>> listeners,
            final Function<T, Duration> reloadAfter); @Override Either<Throwable, T> get(); @Override boolean hasValue();  }
@Test void timeBased() { final Consumer<String> mock = mock(Consumer.class); final Reloadable<String> r = Reloadable.with(() -> UUID.randomUUID() .toString()) .reloadAfter(Duration.ofSeconds(5)) .finishWith(mock) .build(); final Either<Throwable, String> result = r.get(); assertThat(result.get()).isInstanceOf(String.class); verify(mock).accept(any()); final String value = result.get(); assertThat(r.get() .get()).isEqualTo(value); verify(mock, times(1)).accept(any()); }
@Test void timeBasedNoConsumer() { final Reloadable<String> r = Reloadable.with(() -> UUID.randomUUID() .toString()) .reloadAfter(Duration.ofSeconds(5)) .build(); final Either<Throwable, String> result = r.get(); assertThat(result.get()).isInstanceOf(String.class); final String value = result.get(); assertThat(r.get() .get()).isEqualTo(value); }
@Test void finisherFails() { final Consumer<String> finisher = mock(Consumer.class); doThrow(IllegalStateException.class).when(finisher) .accept(any()); final ReloadListener<String> listener = mock(ReloadListener.class); final Reloadable<String> r = Reloadable.with(() -> "") .finishWith(finisher) .addListener(listener) .build(); final Either<Throwable, String> result = r.get(); assertThatThrownBy(result::get).isInstanceOf(NoSuchElementException.class); verify(listener, never()).newValue(any()); verify(listener, never()).valueUnset(); }