package org.fungsi.concurrent; import org.fungsi.Either; import org.fungsi.Unit; import org.fungsi.function.UnsafeRunnable; import org.fungsi.function.UnsafeSupplier; import java.time.Duration; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public final class Timers { private Timers() {} public static Timer wrap(ScheduledExecutorService executor) { return new TimerImpl(executor); } static class TimerImpl implements Timer { private final ScheduledExecutorService executor; TimerImpl(ScheduledExecutorService executor) { this.executor = executor; } @Override public <T> Future<T> flatSchedule(Duration duration, UnsafeSupplier<Future<T>> fn) { Promise<T> p = Promises.create(); executor.schedule(() -> Futures.flatten(fn.safelyGet()).pipeTo(p), duration.toNanos(), TimeUnit.NANOSECONDS); return p; } @Override public <T> Future<T> schedule(Duration interval, UnsafeSupplier<T> fn) { Promise<T> p = Promises.create(); executor.schedule(() -> { Either<T, Throwable> result = fn.safelyGet(); p.set(result); }, interval.toNanos(), TimeUnit.NANOSECONDS); return p; } @Override public Future<Unit> schedule(Duration interval, UnsafeRunnable fn) { Promise<Unit> p = Promises.create(); executor.schedule(() -> { Either<Unit, Throwable> result = fn.safelyRun(); p.set(result); }, interval.toNanos(), TimeUnit.NANOSECONDS); return p; } } }