任务下次运行时间优化:支持Cron、固定间隔等多种时间计算。
This commit is contained in:
parent
51682bce06
commit
25a331be1f
|
@ -8,6 +8,7 @@ import com.xxl.job.admin.core.model.XxlJobUser;
|
||||||
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
|
import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
|
||||||
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
|
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
|
||||||
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
|
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
|
||||||
|
import com.xxl.job.admin.core.thread.JobScheduleHelper;
|
||||||
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
|
import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
|
||||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
||||||
import com.xxl.job.admin.core.util.I18nUtil;
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
|
@ -18,6 +19,8 @@ import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
|
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
|
||||||
import com.xxl.job.core.glue.GlueTypeEnum;
|
import com.xxl.job.core.glue.GlueTypeEnum;
|
||||||
import com.xxl.job.core.util.DateUtil;
|
import com.xxl.job.core.util.DateUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
@ -36,6 +39,7 @@ import java.util.*;
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/jobinfo")
|
@RequestMapping("/jobinfo")
|
||||||
public class JobInfoController {
|
public class JobInfoController {
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(JobInfoController.class);
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private XxlJobGroupDao xxlJobGroupDao;
|
private XxlJobGroupDao xxlJobGroupDao;
|
||||||
|
@ -148,23 +152,29 @@ public class JobInfoController {
|
||||||
|
|
||||||
@RequestMapping("/nextTriggerTime")
|
@RequestMapping("/nextTriggerTime")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ReturnT<List<String>> nextTriggerTime(String cron) {
|
public ReturnT<List<String>> nextTriggerTime(String scheduleType, String scheduleConf) {
|
||||||
|
|
||||||
|
XxlJobInfo paramXxlJobInfo = new XxlJobInfo();
|
||||||
|
paramXxlJobInfo.setScheduleType(scheduleType);
|
||||||
|
paramXxlJobInfo.setScheduleConf(scheduleConf);
|
||||||
|
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
CronExpression cronExpression = new CronExpression(cron);
|
|
||||||
Date lastTime = new Date();
|
Date lastTime = new Date();
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
lastTime = cronExpression.getNextValidTimeAfter(lastTime);
|
lastTime = JobScheduleHelper.generateNextValidTime(paramXxlJobInfo, lastTime);
|
||||||
if (lastTime != null) {
|
if (lastTime != null) {
|
||||||
result.add(DateUtil.formatDateTime(lastTime));
|
result.add(DateUtil.formatDateTime(lastTime));
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ParseException e) {
|
} catch (Exception e) {
|
||||||
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid"));
|
logger.error(e.getMessage(), e);
|
||||||
|
return new ReturnT<List<String>>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) + e.getMessage());
|
||||||
}
|
}
|
||||||
return new ReturnT<List<String>>(result);
|
return new ReturnT<List<String>>(result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,11 +79,11 @@ public class XxlJobServiceImpl implements XxlJobService {
|
||||||
}
|
}
|
||||||
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
|
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
|
||||||
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
||||||
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid"));
|
||||||
}
|
}
|
||||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE/* || scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
||||||
if (jobInfo.getScheduleConf() == null) {
|
if (jobInfo.getScheduleConf() == null) {
|
||||||
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
|
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")) );
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
|
int fixSecond = Integer.valueOf(jobInfo.getScheduleConf());
|
||||||
|
@ -183,7 +183,7 @@ public class XxlJobServiceImpl implements XxlJobService {
|
||||||
}
|
}
|
||||||
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
|
if (scheduleTypeEnum == ScheduleTypeEnum.CRON) {
|
||||||
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
if (jobInfo.getScheduleConf()==null || !CronExpression.isValidExpression(jobInfo.getScheduleConf())) {
|
||||||
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") );
|
return new ReturnT<String>(ReturnT.FAIL_CODE, "Cron"+I18nUtil.getString("system_unvalid") );
|
||||||
}
|
}
|
||||||
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
} else if (scheduleTypeEnum == ScheduleTypeEnum.FIX_RATE /*|| scheduleTypeEnum == ScheduleTypeEnum.FIX_DELAY*/) {
|
||||||
if (jobInfo.getScheduleConf() == null) {
|
if (jobInfo.getScheduleConf() == null) {
|
||||||
|
|
|
@ -117,7 +117,6 @@ jobinfo_field_jobdesc=Job description
|
||||||
jobinfo_field_timeout=Job timeout period
|
jobinfo_field_timeout=Job timeout period
|
||||||
jobinfo_field_gluetype=GLUE Type
|
jobinfo_field_gluetype=GLUE Type
|
||||||
jobinfo_field_executorparam=Param
|
jobinfo_field_executorparam=Param
|
||||||
jobinfo_field_cron_unvalid=The Cron is illegal
|
|
||||||
jobinfo_field_author=Author
|
jobinfo_field_author=Author
|
||||||
jobinfo_field_alarmemail=Alarm email
|
jobinfo_field_alarmemail=Alarm email
|
||||||
jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated
|
jobinfo_field_alarmemail_placeholder=Please enter alarm mail, if there are more than one comma separated
|
||||||
|
|
|
@ -116,7 +116,6 @@ jobinfo_field_jobgroup=执行器
|
||||||
jobinfo_field_jobdesc=任务描述
|
jobinfo_field_jobdesc=任务描述
|
||||||
jobinfo_field_gluetype=运行模式
|
jobinfo_field_gluetype=运行模式
|
||||||
jobinfo_field_executorparam=任务参数
|
jobinfo_field_executorparam=任务参数
|
||||||
jobinfo_field_cron_unvalid=Cron格式非法
|
|
||||||
jobinfo_field_author=负责人
|
jobinfo_field_author=负责人
|
||||||
jobinfo_field_timeout=任务超时时间
|
jobinfo_field_timeout=任务超时时间
|
||||||
jobinfo_field_alarmemail=报警邮件
|
jobinfo_field_alarmemail=报警邮件
|
||||||
|
|
|
@ -116,7 +116,6 @@ jobinfo_field_jobgroup=執行器
|
||||||
jobinfo_field_jobdesc=任務描述
|
jobinfo_field_jobdesc=任務描述
|
||||||
jobinfo_field_gluetype=運行模式
|
jobinfo_field_gluetype=運行模式
|
||||||
jobinfo_field_executorparam=任務參數
|
jobinfo_field_executorparam=任務參數
|
||||||
jobinfo_field_cron_unvalid=Cron 格式非法
|
|
||||||
jobinfo_field_author=負責人
|
jobinfo_field_author=負責人
|
||||||
jobinfo_field_timeout=任務超時秒數
|
jobinfo_field_timeout=任務超時秒數
|
||||||
jobinfo_field_alarmemail=告警郵件
|
jobinfo_field_alarmemail=告警郵件
|
||||||
|
|
|
@ -118,10 +118,16 @@ $(function() {
|
||||||
start_stop_div = '<li><a href="javascript:void(0);" class="job_operate" _type="job_resume" >'+ I18n.jobinfo_opt_start +'</a></li>\n';
|
start_stop_div = '<li><a href="javascript:void(0);" class="job_operate" _type="job_resume" >'+ I18n.jobinfo_opt_start +'</a></li>\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// job_next_time_html
|
||||||
|
var job_next_time_html = '';
|
||||||
|
if (row.scheduleType == 'CRON' || row.scheduleType == 'FIX_RATE') {
|
||||||
|
job_next_time_html = '<li><a href="javascript:void(0);" class="job_next_time" >' + I18n.jobinfo_opt_next_time + '</a></li>\n';
|
||||||
|
}
|
||||||
|
|
||||||
// log url
|
// log url
|
||||||
var logHref = base_url +'/joblog?jobId='+ row.id;
|
var logHref = base_url +'/joblog?jobId='+ row.id;
|
||||||
|
|
||||||
// log url
|
// code url
|
||||||
var codeBtn = "";
|
var codeBtn = "";
|
||||||
if ('BEAN' != row.glueType) {
|
if ('BEAN' != row.glueType) {
|
||||||
var codeUrl = base_url +'/jobcode?jobId='+ row.id;
|
var codeUrl = base_url +'/jobcode?jobId='+ row.id;
|
||||||
|
@ -143,7 +149,7 @@ $(function() {
|
||||||
' <li><a href="javascript:void(0);" class="job_trigger" >'+ I18n.jobinfo_opt_run +'</a></li>\n' +
|
' <li><a href="javascript:void(0);" class="job_trigger" >'+ I18n.jobinfo_opt_run +'</a></li>\n' +
|
||||||
' <li><a href="'+ logHref +'">'+ I18n.jobinfo_opt_log +'</a></li>\n' +
|
' <li><a href="'+ logHref +'">'+ I18n.jobinfo_opt_log +'</a></li>\n' +
|
||||||
' <li><a href="javascript:void(0);" class="job_registryinfo" >' + I18n.jobinfo_opt_registryinfo + '</a></li>\n' +
|
' <li><a href="javascript:void(0);" class="job_registryinfo" >' + I18n.jobinfo_opt_registryinfo + '</a></li>\n' +
|
||||||
' <li><a href="javascript:void(0);" class="job_next_time" >' + I18n.jobinfo_opt_next_time + '</a></li>\n' +
|
job_next_time_html +
|
||||||
' <li class="divider"></li>\n' +
|
' <li class="divider"></li>\n' +
|
||||||
codeBtn +
|
codeBtn +
|
||||||
start_stop_div +
|
start_stop_div +
|
||||||
|
@ -329,17 +335,16 @@ $(function() {
|
||||||
var id = $(this).parents('ul').attr("_id");
|
var id = $(this).parents('ul').attr("_id");
|
||||||
var row = tableData['key'+id];
|
var row = tableData['key'+id];
|
||||||
|
|
||||||
var jobCron = row.jobCron;
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type : 'POST',
|
type : 'POST',
|
||||||
url : base_url + "/jobinfo/nextTriggerTime",
|
url : base_url + "/jobinfo/nextTriggerTime",
|
||||||
data : {
|
data : {
|
||||||
"cron" : jobCron
|
"scheduleType" : row.scheduleType,
|
||||||
|
"scheduleConf" : row.scheduleConf
|
||||||
},
|
},
|
||||||
dataType : "json",
|
dataType : "json",
|
||||||
success : function(data){
|
success : function(data){
|
||||||
|
|
||||||
if (data.code != 200) {
|
if (data.code != 200) {
|
||||||
layer.open({
|
layer.open({
|
||||||
title: I18n.jobinfo_opt_next_time ,
|
title: I18n.jobinfo_opt_next_time ,
|
||||||
|
@ -585,9 +590,6 @@ $(function() {
|
||||||
required : true,
|
required : true,
|
||||||
maxlength: 50
|
maxlength: 50
|
||||||
},
|
},
|
||||||
jobCron : {
|
|
||||||
required : true
|
|
||||||
},
|
|
||||||
author : {
|
author : {
|
||||||
required : true
|
required : true
|
||||||
}
|
}
|
||||||
|
@ -596,9 +598,6 @@ $(function() {
|
||||||
jobDesc : {
|
jobDesc : {
|
||||||
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
|
required : I18n.system_please_input + I18n.jobinfo_field_jobdesc
|
||||||
},
|
},
|
||||||
jobCron : {
|
|
||||||
required : I18n.system_please_input + "Cron"
|
|
||||||
},
|
|
||||||
author : {
|
author : {
|
||||||
required : I18n.system_please_input + I18n.jobinfo_field_author
|
required : I18n.system_please_input + I18n.jobinfo_field_author
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,7 +641,8 @@
|
||||||
type : 'GET',
|
type : 'GET',
|
||||||
url : base_url + "/jobinfo/nextTriggerTime",
|
url : base_url + "/jobinfo/nextTriggerTime",
|
||||||
data : {
|
data : {
|
||||||
"cron" : inputElement.val(),
|
"scheduleType" : 'CRON',
|
||||||
|
"scheduleConf" : inputElement.val()
|
||||||
},
|
},
|
||||||
dataType : "json",
|
dataType : "json",
|
||||||
success : function(data){
|
success : function(data){
|
||||||
|
|
|
@ -641,7 +641,8 @@
|
||||||
type : 'GET',
|
type : 'GET',
|
||||||
url : base_url + "/jobinfo/nextTriggerTime",
|
url : base_url + "/jobinfo/nextTriggerTime",
|
||||||
data : {
|
data : {
|
||||||
"cron" : inputElement.val(),
|
"scheduleType" : 'CRON',
|
||||||
|
"scheduleConf" : inputElement.val()
|
||||||
},
|
},
|
||||||
dataType : "json",
|
dataType : "json",
|
||||||
success : function(data){
|
success : function(data){
|
||||||
|
|
Loading…
Reference in New Issue