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

com.github.ltsopensource.jobtracker.support.NonRelyOnPrevCycleJobScheduler Maven / Gradle / Ivy

package com.github.ltsopensource.jobtracker.support;

import com.github.ltsopensource.core.commons.utils.Callable;
import com.github.ltsopensource.core.commons.utils.CollectionUtils;
import com.github.ltsopensource.core.commons.utils.DateUtils;
import com.github.ltsopensource.core.constant.ExtConfig;
import com.github.ltsopensource.core.exception.LtsRuntimeException;
import com.github.ltsopensource.core.factory.NamedThreadFactory;
import com.github.ltsopensource.core.logger.Logger;
import com.github.ltsopensource.core.logger.LoggerFactory;
import com.github.ltsopensource.core.support.NodeShutdownHook;
import com.github.ltsopensource.jobtracker.domain.JobTrackerAppContext;
import com.github.ltsopensource.queue.domain.JobPo;
import com.github.ltsopensource.queue.support.NonRelyJobUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 仅用于不依赖上一周期的任务生成器
 * @author Robert HG ([email protected]) on 4/2/16.
 */
public class NonRelyOnPrevCycleJobScheduler {

    private static final Logger LOGGER = LoggerFactory.getLogger(NonRelyOnPrevCycleJobScheduler.class);
    private JobTrackerAppContext appContext;
    private int scheduleIntervalMinute;
    private ScheduledExecutorService executorService;
    private ScheduledFuture scheduledFuture;
    private AtomicBoolean running = new AtomicBoolean(false);

    private AtomicBoolean start = new AtomicBoolean(false);

    public NonRelyOnPrevCycleJobScheduler(JobTrackerAppContext appContext) {
        this.appContext = appContext;
        this.scheduleIntervalMinute = this.appContext.getConfig().getParameter(ExtConfig.JOB_TRACKER_NON_RELYON_PREV_CYCLE_JOB_SCHEDULER_INTERVAL_MINUTE, 10);

        NodeShutdownHook.registerHook(appContext, this.getClass().getSimpleName(), new Callable() {
            @Override
            public void call() throws Exception {
                stop();
            }
        });
    }

    public void start() {
        if (!start.compareAndSet(false, true)) {
            return;
        }
        try {
            executorService = Executors.newScheduledThreadPool(1, new NamedThreadFactory(NonRelyOnPrevCycleJobScheduler.class.getSimpleName(), true));
            this.scheduledFuture = executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (running.compareAndSet(false, true)) {
                            try {
                                schedule();
                            } finally {
                                running.set(false);
                            }
                        }
                    } catch (Throwable t) {
                        LOGGER.error("Error On Schedule", t);
                    }
                }
            }, 10, (scheduleIntervalMinute - 1) * 60, TimeUnit.SECONDS);
        } catch (Throwable t) {
            LOGGER.error("Scheduler Start Error", t);
        }
    }

    public void stop() {
        if (!start.compareAndSet(true, false)) {
            return;
        }
        try {
            if (scheduledFuture != null) {
                scheduledFuture.cancel(true);
            }
            if (executorService != null) {
                executorService.shutdownNow();
                executorService = null;
            }
        } catch (Throwable t) {
            LOGGER.error("Scheduler Stop Error", t);
        }
    }

    private void schedule() {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("========= Scheduler start =========");
        }

        Date now = new Date();
        Date checkTime = DateUtils.addMinute(now, 10);
        //  cron任务
        while (true) {
            List jobPos = appContext.getCronJobQueue().getNeedGenerateJobPos(checkTime.getTime(), 10);
            if (CollectionUtils.sizeOf(jobPos) == 0) {
                break;
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("========= CronJob size[{}] =========", CollectionUtils.sizeOf(jobPos));
            }
            for (JobPo jobPo : jobPos) {
                Long lastGenerateTriggerTime = jobPo.getLastGenerateTriggerTime();
                if (lastGenerateTriggerTime == null || lastGenerateTriggerTime == 0) {
                    lastGenerateTriggerTime = new Date().getTime();
                }
                addCronJobForInterval(jobPo, new Date(lastGenerateTriggerTime));
            }
        }

        // repeat 任务
        while (true) {
            List jobPos = appContext.getRepeatJobQueue().getNeedGenerateJobPos(checkTime.getTime(), 10);
            if (CollectionUtils.sizeOf(jobPos) == 0) {
                break;
            }
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("========= Repeat size[{}] =========", CollectionUtils.sizeOf(jobPos));
            }
            for (JobPo jobPo : jobPos) {
                Long lastGenerateTriggerTime = jobPo.getLastGenerateTriggerTime();
                if (lastGenerateTriggerTime == null || lastGenerateTriggerTime == 0) {
                    lastGenerateTriggerTime = new Date().getTime();
                }
                addRepeatJobForInterval(jobPo, new Date(lastGenerateTriggerTime));
            }
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("========= Scheduler End =========");
        }
    }

    public void addScheduleJobForOneHour(JobPo jobPo) {
        if (jobPo.isCron()) {
            addCronJobForInterval(jobPo, new Date());
        } else if (jobPo.isRepeatable()) {
            addRepeatJobForInterval(jobPo, new Date());
        } else {
            throw new LtsRuntimeException("Only For Cron Or Repeat Job Now");
        }
    }

    private void addCronJobForInterval(final JobPo finalJobPo, Date lastGenerateTime) {
        NonRelyJobUtils.addCronJobForInterval(appContext.getExecutableJobQueue(), appContext.getCronJobQueue(),
                scheduleIntervalMinute, finalJobPo, lastGenerateTime);
    }

    private void addRepeatJobForInterval(final JobPo finalJobPo, Date lastGenerateTime) {
        NonRelyJobUtils.addRepeatJobForInterval(appContext.getExecutableJobQueue(), appContext.getRepeatJobQueue(),
                scheduleIntervalMinute, finalJobPo, lastGenerateTime);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy