All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.diversionmc.async.schedule.Scheduler Maven / Gradle / Ivy

package net.diversionmc.async.schedule;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

import static java.lang.System.nanoTime;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static net.diversionmc.async.schedule.ThreadPoolScheduler.SCHEDULER;

/**
 * Scheduler assigns a thread to perform an action in.
 */
@FunctionalInterface
public interface Scheduler {
    /**
     * Schedule to immediately run a task.
     *
     * @param asyncAction Action to perform.
     */
    Future schedule(Runnable asyncAction);
    
    /**
     * Schedule to repeatedly run a task.
     * Default implementation is using {@link #schedule(Runnable)} and blocking the thread the task used there.
     *
     * @param period      Period between iterations.
     * @param unit        Period unit.
     * @param asyncAction Action to perform.
     */
    default Future scheduleRepeating(long period, TimeUnit unit, Consumer asyncAction) {
        return schedule(() -> {
            var iter = new AtomicInteger();
            var loop = new LoopState(iter);
            while (true) {
                long start = nanoTime();
                try {
                    asyncAction.accept(loop);
                } catch (Throwable t) {
                    loop.stop(); // mark as stopped for non-pure function leaky bois
                    //noinspection ProhibitedExceptionThrown
                    throw t;
                }

                if (loop.stopped()) break;
                
                long time = NANOSECONDS.convert(period, unit);
                long delta = nanoTime() - start;
                if (delta < time) try {
                    var lock = SCHEDULER.runLock();
                    if (lock.tryLock(time - delta, NANOSECONDS)) {
                        loop.stop();
                        lock.unlock();
                        break;
                    }
                } catch (InterruptedException ignored) {
                }

                iter.getAndIncrement();
            }
        });
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy