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

io.mangoo.scheduler.CronTask Maven / Gradle / Ivy

The newest version!
package io.mangoo.scheduler;

import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import io.mangoo.constants.NotNull;
import io.mangoo.core.Application;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class CronTask implements Runnable {
    private static final Logger LOG = LogManager.getLogger(CronTask.class);
    private final Class clazz;
    private final String methodName;
    private final ExecutionTime executionTime;
    
    public CronTask(Class clazz, String methodName, String cron) {
        Objects.requireNonNull(cron, NotNull.CRON);
        this.clazz = Objects.requireNonNull(clazz, NotNull.CLASS);
        this.methodName = Objects.requireNonNull(methodName, NotNull.METHOD);
        this.executionTime = ExecutionTime.forCron(new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)).parse(cron));
    }

    @Override
    @SuppressWarnings("all")
    public void run() {
        try {
            long delay = delay();
            if (delay > 0) {
                Task task = new Task(clazz, methodName);
                Application.getScheduledExecutorService().schedule(task, delay, TimeUnit.SECONDS).get();
            }
        } catch (Exception e) {
            LOG.error("Failed to execute scheduled cron task on class '{}' with annotated method '{}'", clazz.getName(), methodName, e);
        }
        
        run();
    }
    
    private long delay() throws ExecutionException, InterruptedException {
        if (secondsToNextExecution() == 0) {
            try (ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, Thread.ofVirtual().factory())) {
                executor.schedule(() -> {}, 1, TimeUnit.SECONDS).get();
            }
        }

        return secondsToNextExecution();
    }

    private long secondsToNextExecution() {
        return executionTime
                .timeToNextExecution(ZonedDateTime.now())
                .orElse(Duration.ofSeconds(-1))
                .getSeconds();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy