|
@@ -0,0 +1,173 @@
|
|
|
+package com.css.simulation.resource.monitor.scheduler;
|
|
|
+
|
|
|
+import api.common.util.ObjectUtil;
|
|
|
+import com.css.simulation.resource.monitor.feign.ProjectService;
|
|
|
+import lombok.Data;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.Trigger;
|
|
|
+import org.springframework.scheduling.TriggerContext;
|
|
|
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
|
|
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|
|
+import org.springframework.scheduling.support.CronExpression;
|
|
|
+import org.springframework.scheduling.support.CronTrigger;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
|
+
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class ProjectScheduler implements SchedulingConfigurer {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ ProjectService projectService;
|
|
|
+
|
|
|
+ static ProjectService staticProjectService;
|
|
|
+
|
|
|
+ private ScheduledTaskRegistrar taskRegistrar;
|
|
|
+ private final Map<String, ScheduledFuture> scheduledFutures = new HashMap<>();
|
|
|
+ private final Map<String, ProjectTask> projectTasks = new HashMap<>();
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void postConstruct() {
|
|
|
+ staticProjectService = this.projectService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
|
|
|
+ this.taskRegistrar = taskRegistrar;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化任务
|
|
|
+ */
|
|
|
+ public int init(List<ProjectTask> projectTask){
|
|
|
+ if(ObjectUtil.isNull(projectTask)){
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ //停止旧任务
|
|
|
+ destroy();
|
|
|
+ int count = 0;
|
|
|
+ for (ProjectTask task : projectTask) {
|
|
|
+ if(start(task)){
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ //返回启动成功的任务数量
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开启任务
|
|
|
+ */
|
|
|
+ public boolean start(ProjectTask task){
|
|
|
+ if(!validate(task)){
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+ String projectId = task.getProjectId();
|
|
|
+ String cron = task.getCron();
|
|
|
+ //任务已经存在,并且cron表达式没有变动,直接返回
|
|
|
+ if(scheduledFutures.containsKey(projectId)){
|
|
|
+ if(projectTasks.containsKey(projectId)){
|
|
|
+ ProjectTask projectTask = projectTasks.get(projectId);
|
|
|
+ if(projectTask.getCron().equals(cron)){
|
|
|
+ return true;
|
|
|
+ }else{
|
|
|
+ //有变动就停止
|
|
|
+ scheduledFutures.get(projectId).cancel(false);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //开启新任务
|
|
|
+ ScheduledFuture<?> schedule = taskRegistrar.getScheduler().schedule(task, new Trigger() {
|
|
|
+ @Override
|
|
|
+ public Date nextExecutionTime(TriggerContext triggerContext) {
|
|
|
+ CronTrigger cronTrigger = new CronTrigger(cron);
|
|
|
+ Date date = cronTrigger.nextExecutionTime(triggerContext);
|
|
|
+ return date;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ //放入缓存
|
|
|
+ projectTasks.put(projectId,task);
|
|
|
+ scheduledFutures.put(projectId,schedule);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停止任务
|
|
|
+ */
|
|
|
+ public boolean stop(ProjectTask task){
|
|
|
+ if(ObjectUtil.isNull(task) || ObjectUtil.isNull(task.getProjectId())){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //任务已经存在,停止
|
|
|
+ String projectId = task.getProjectId();
|
|
|
+ if(scheduledFutures.containsKey(projectId)){
|
|
|
+ scheduledFutures.get(projectId).cancel(false);
|
|
|
+ //清除缓存
|
|
|
+ projectTasks.remove(projectId);
|
|
|
+ scheduledFutures.remove(projectId);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清空所有任务
|
|
|
+ */
|
|
|
+ public void destroy(){
|
|
|
+ //停止现有任务
|
|
|
+ scheduledFutures.forEach((k,v)->{
|
|
|
+ //运行中不允许中断,完成后再停止
|
|
|
+ v.cancel(false);
|
|
|
+ });
|
|
|
+ //清空缓存
|
|
|
+ scheduledFutures.clear();
|
|
|
+ projectTasks.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean validate(ProjectTask task) {
|
|
|
+ if(ObjectUtil.isNull(task)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(ObjectUtil.isNull(task.getProjectId()) || ObjectUtil.isNull(task.getCron())){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ //校验cron表达式
|
|
|
+ try {
|
|
|
+ CronExpression.parse(task.getCron());
|
|
|
+ }catch (Exception e){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 继承该类,重写run方法,即可自定义任务执行逻辑
|
|
|
+ */
|
|
|
+ @Data
|
|
|
+ public static class ProjectTask implements Runnable{
|
|
|
+
|
|
|
+ public ProjectTask() {}
|
|
|
+
|
|
|
+ private String projectId;
|
|
|
+
|
|
|
+ private String cron;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ log.info("projectTask [" + projectId + "] run : " + new Date());
|
|
|
+ Map<String,String> projectParam = new HashMap<>();
|
|
|
+ projectParam.put("id",projectId);
|
|
|
+ ProjectScheduler.staticProjectService.runProject(projectParam);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|