From 6af24ec0ecc73ff314c6827bb0059872c1ad7f63 Mon Sep 17 00:00:00 2001 From: wangshaoping Date: Wed, 27 Dec 2023 13:50:54 +0800 Subject: [PATCH] add theme update --- .../platform/components/grid/TableAction.vue | 1 - .../src/platform/components/grid/TableRow.vue | 53 +++ .../platform/components/grid/WListGrid.vue | 19 +- .../src/views/Table.vue | 18 +- .../template-project/src/views/Table.vue | 91 ++--- .../template-project/src/views/TableTitle.vue | 118 ++++++ .../package.json | 4 +- io.sc.platform.job.core/build.gradle | 6 + .../job/core/enums/BlockStrategy.java | 7 + .../job/core/enums/ExecutorRouteStrategy.java | 14 + .../job/core/enums/ExpirationPolicy.java | 6 + .../sc/platform/job/core/enums/GlueType.java | 11 + .../job/core/enums/TaskScheduleType.java | 7 + .../job/core/enums/TriggerStatus.java | 6 + .../job/core/thread/JobCompleteHelper.java | 179 +++++++++ .../job/core/thread/JobFailMonitorHelper.java | 110 ++++++ .../job/core/thread/JobLogReportHelper.java | 152 ++++++++ .../job/core/thread/JobRegistryHelper.java | 204 ++++++++++ .../job/core/thread/JobScheduleHelper.java | 368 ++++++++++++++++++ .../job/core/thread/JobTriggerPoolHelper.java | 150 +++++++ .../job/core/vo/ExecutorRegistryVo.java | 53 +++ .../sc/platform/job/core/vo/ExecutorVo.java | 63 +++ .../platform/job/core/vo/TaskLogReportVo.java | 62 +++ .../io/sc/platform/job/core/vo/TaskLogVo.java | 143 +++++++ .../io/sc/platform/job/core/vo/TaskVo.java | 189 +++++++++ ...obGroupEntity.java => ExecutorEntity.java} | 63 +-- .../jpa/entity/ExecutorRegistryEntity.java | 91 +++++ .../job/manager/jpa/entity/TaskEntity.java | 299 ++++++++++++++ .../job/manager/jpa/entity/TaskLogEntity.java | 230 +++++++++++ .../jpa/entity/TaskLogReportEntity.java | 99 +++++ .../ExecutorRegistryRepository.java | 12 + ...epository.java => ExecutorRepository.java} | 6 +- .../repository/TaskLogReportRepository.java | 8 + .../jpa/repository/TaskLogRepository.java | 7 + .../jpa/repository/TaskRepository.java | 8 + .../job/manager/service/TaskService.java | 10 + .../manager/service/impl/TaskServiceImpl.java | 58 +++ .../liquibase/PF_8.0.0_20220606__Job_DDL.xml | 166 ++++++++ io.sc.platform.lcdp.frontend/package.json | 4 +- io.sc.platform.mvc.frontend/package.json | 4 +- io.sc.platform.security.frontend/package.json | 4 +- io.sc.platform.system.frontend/package.json | 2 +- .../system/role/jpa/entity/RoleEntity.java | 1 - 43 files changed, 3000 insertions(+), 106 deletions(-) create mode 100644 io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue create mode 100644 io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue create mode 100644 io.sc.platform.job.core/build.gradle create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java create mode 100644 io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java rename io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/{JobGroupEntity.java => ExecutorEntity.java} (55%) create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java rename io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/{JobGroupRepository.java => ExecutorRepository.java} (57%) create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java create mode 100644 io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java diff --git a/io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue b/io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue index 9460a880..b97c270f 100644 --- a/io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue +++ b/io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue @@ -99,7 +99,6 @@ const onResize = (size) => { let index = 0; for (; index < length; index++) { - console.log(index, width + actions[index].width, availableWidth); if (width + actions[index].width > availableWidth) { availableWidth -= moreActionWidth; while (width > availableWidth) { diff --git a/io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue b/io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue new file mode 100644 index 00000000..523ac549 --- /dev/null +++ b/io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue @@ -0,0 +1,53 @@ + + diff --git a/io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue b/io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue index 15ac7dbf..2c1113ef 100644 --- a/io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue +++ b/io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue @@ -17,7 +17,6 @@ @@ -51,6 +35,7 @@ import { ref, computed, onMounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { axios, Tools, TreeBuilder } from '@/platform'; import TableAction from './TableAction.vue'; +import TableRow from './TableRow.vue'; const props = defineProps({ tree: { type: Boolean, default: false }, diff --git a/io.sc.platform.core.frontend/src/views/Table.vue b/io.sc.platform.core.frontend/src/views/Table.vue index 94fb1370..16438869 100644 --- a/io.sc.platform.core.frontend/src/views/Table.vue +++ b/io.sc.platform.core.frontend/src/views/Table.vue @@ -38,17 +38,19 @@ const columns = [ { name: 'name', required: true, - label: 'Dessert (100g serving)', + label: t('name'), align: 'left', field: 'name', sortable: true, + format: (value, data) => { + return t(data.titleI18nKey); + }, }, - { name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, - { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, - { name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, - { name: 'protein', label: 'Protein (g)', field: 'protein' }, - { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, - { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, - { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, + { name: 'type', align: 'center', label: 'type', field: 'type', sortable: true }, + { name: 'enable', label: 'enable', field: 'enable', sortable: true }, + { name: 'dataComeFrom', label: 'dataComeFrom', field: 'dataComeFrom' }, + { name: 'lastModifier', label: 'lastModifier', field: 'lastModifier' }, + { name: 'lastModifyDate', label: 'lastModifyDate', field: 'lastModifyDate' }, + { name: 'corporationCode', label: 'corporationCode', field: 'corporationCode', sortable: true }, ]; diff --git a/io.sc.platform.core.frontend/template-project/src/views/Table.vue b/io.sc.platform.core.frontend/template-project/src/views/Table.vue index 9d38561c..94fb1370 100644 --- a/io.sc.platform.core.frontend/template-project/src/views/Table.vue +++ b/io.sc.platform.core.frontend/template-project/src/views/Table.vue @@ -1,53 +1,54 @@ + diff --git a/io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue b/io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue new file mode 100644 index 00000000..17ee9b13 --- /dev/null +++ b/io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue @@ -0,0 +1,118 @@ + + diff --git a/io.sc.platform.developer.frontend/package.json b/io.sc.platform.developer.frontend/package.json index ad76cf84..aa1f3c8d 100644 --- a/io.sc.platform.developer.frontend/package.json +++ b/io.sc.platform.developer.frontend/package.json @@ -1,6 +1,6 @@ { "name": "io.sc.platform.developer.frontend", - "version": "8.1.19", + "version": "8.1.20", "description": "", "private": false, "keywords": [ @@ -79,7 +79,7 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.45", + "platform-core": "8.1.47", "quasar": "2.13.0", "tailwindcss": "3.3.5", "vue": "3.3.7", diff --git a/io.sc.platform.job.core/build.gradle b/io.sc.platform.job.core/build.gradle new file mode 100644 index 00000000..a9349765 --- /dev/null +++ b/io.sc.platform.job.core/build.gradle @@ -0,0 +1,6 @@ +dependencies { + api( + project(":io.sc.platform.core"), + project(":io.sc.platform.orm.api"), + ) +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java new file mode 100644 index 00000000..091d972a --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java @@ -0,0 +1,7 @@ +package io.sc.platform.job.core.enums; + +public enum BlockStrategy { + SERIAL_EXECUTION, //单机串行 + DISCARD_LATER, //丢弃后续调度 + COVER_EARLY; //覆盖先前调度 +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java new file mode 100644 index 00000000..8a327ffb --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java @@ -0,0 +1,14 @@ +package io.sc.platform.job.core.enums; + +public enum ExecutorRouteStrategy { + FIRST, //第一个 + LAST, //最后一个 + ROUND, //轮询 + RANDOM, //随机 + CONSISTENT_HASH, //一致性 Hash + LEAST_FREQUENTLY_USED, //最不经常使用 + LEAST_RECENTLY_USED, //最近最久未使用 + FAILOVER, //故障转移 + BUSYOVER, //忙碌转义 + SHARDING_BROADCAST; //分片广播 +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java new file mode 100644 index 00000000..dddb65c6 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java @@ -0,0 +1,6 @@ +package io.sc.platform.job.core.enums; + +public enum ExpirationPolicy { + DO_NOTHING, //忽略 + FIRE_ONCE_NOW; //立即执行一次 +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java new file mode 100644 index 00000000..2ed9eb4d --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java @@ -0,0 +1,11 @@ +package io.sc.platform.job.core.enums; + +public enum GlueType { + BEAN, // Bean + GLUE_GROOVY, // groovy + GLUE_SHELL, // shell + GLUE_PYTHON, // python + GLUE_PHP, // php + GLUE_NODEJS, // nodejs + GLUE_POWERSHELL;// powershell +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java new file mode 100644 index 00000000..f5f31604 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java @@ -0,0 +1,7 @@ +package io.sc.platform.job.core.enums; + +public enum TaskScheduleType { + NONE, //无 + CRON, //Cron + FIX_RATE; //固定周期 +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java new file mode 100644 index 00000000..d4b021fe --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java @@ -0,0 +1,6 @@ +package io.sc.platform.job.core.enums; + +public enum TriggerStatus { + STOPED, //已停止 + RUNNING; //运行中 +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java new file mode 100644 index 00000000..1f28ae24 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java @@ -0,0 +1,179 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.complete.XxlJobCompleter; +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.model.HandleCallbackParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.util.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; +import java.util.List; +import java.util.concurrent.*; + +public class JobCompleteHelper { + private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class); + + private static JobCompleteHelper instance = new JobCompleteHelper(); + public static JobCompleteHelper getInstance(){ + return instance; + } + + // ---------------------- monitor ---------------------- + + private ThreadPoolExecutor callbackThreadPool = null; + private Thread monitorThread; + private volatile boolean toStop = false; + public void start(){ + + // for callback + callbackThreadPool = new ThreadPoolExecutor( + 2, + 20, + 30L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(3000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode()); + } + }, + new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + r.run(); + logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now)."); + } + }); + + + // for monitor + monitorThread = new Thread(new Runnable() { + + @Override + public void run() { + + // wait for JobTriggerPoolHelper-init + try { + TimeUnit.MILLISECONDS.sleep(50); + } catch (InterruptedException e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + // monitor + while (!toStop) { + try { + // 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败; + Date losedTime = DateUtil.addMinutes(new Date(), -10); + List losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime); + + if (losedJobIds!=null && losedJobIds.size()>0) { + for (Long logId: losedJobIds) { + + XxlJobLog jobLog = new XxlJobLog(); + jobLog.setId(logId); + + jobLog.setHandleTime(new Date()); + jobLog.setHandleCode(ReturnT.FAIL_CODE); + jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") ); + + XxlJobCompleter.updateHandleInfoAndFinish(jobLog); + } + + } + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); + } + } + + try { + TimeUnit.SECONDS.sleep(60); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop"); + + } + }); + monitorThread.setDaemon(true); + monitorThread.setName("xxl-job, admin JobLosedMonitorHelper"); + monitorThread.start(); + } + + public void toStop(){ + toStop = true; + + // stop registryOrRemoveThreadPool + callbackThreadPool.shutdownNow(); + + // stop monitorThread (interrupt and wait) + monitorThread.interrupt(); + try { + monitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + + // ---------------------- helper ---------------------- + + public ReturnT callback(List callbackParamList) { + + callbackThreadPool.execute(new Runnable() { + @Override + public void run() { + for (HandleCallbackParam handleCallbackParam: callbackParamList) { + ReturnT callbackResult = callback(handleCallbackParam); + logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}", + (callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult); + } + } + }); + + return ReturnT.SUCCESS; + } + + private ReturnT callback(HandleCallbackParam handleCallbackParam) { + // valid log item + XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId()); + if (log == null) { + return new ReturnT(ReturnT.FAIL_CODE, "log item not found."); + } + if (log.getHandleCode() > 0) { + return new ReturnT(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc + } + + // handle msg + StringBuffer handleMsg = new StringBuffer(); + if (log.getHandleMsg()!=null) { + handleMsg.append(log.getHandleMsg()).append("
"); + } + if (handleCallbackParam.getHandleMsg() != null) { + handleMsg.append(handleCallbackParam.getHandleMsg()); + } + + // success, save log + log.setHandleTime(new Date()); + log.setHandleCode(handleCallbackParam.getHandleCode()); + log.setHandleMsg(handleMsg.toString()); + XxlJobCompleter.updateHandleInfoAndFinish(log); + + return ReturnT.SUCCESS; + } + + + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java new file mode 100644 index 00000000..c0ee741e --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java @@ -0,0 +1,110 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.util.I18nUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * job monitor instance + * + * @author xuxueli 2015-9-1 18:05:56 + */ +public class JobFailMonitorHelper { + private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class); + + private static JobFailMonitorHelper instance = new JobFailMonitorHelper(); + public static JobFailMonitorHelper getInstance(){ + return instance; + } + + // ---------------------- monitor ---------------------- + + private Thread monitorThread; + private volatile boolean toStop = false; + public void start(){ + monitorThread = new Thread(new Runnable() { + + @Override + public void run() { + + // monitor + while (!toStop) { + try { + + List failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000); + if (failLogIds!=null && !failLogIds.isEmpty()) { + for (long failLogId: failLogIds) { + + // lock log + int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1); + if (lockRet < 1) { + continue; + } + XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId); + XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId()); + + // 1、fail retry monitor + if (log.getExecutorFailRetryCount() > 0) { + JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam(), null); + String retryMsg = "

>>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<<
"; + log.setTriggerMsg(log.getTriggerMsg() + retryMsg); + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log); + } + + // 2、fail alarm monitor + int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败 + if (info != null) { + boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log); + newAlarmStatus = alarmResult?2:3; + } else { + newAlarmStatus = 1; + } + + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus); + } + } + + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e); + } + } + + try { + TimeUnit.SECONDS.sleep(10); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop"); + + } + }); + monitorThread.setDaemon(true); + monitorThread.setName("xxl-job, admin JobFailMonitorHelper"); + monitorThread.start(); + } + + public void toStop(){ + toStop = true; + // interrupt and wait + monitorThread.interrupt(); + try { + monitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java new file mode 100644 index 00000000..80c5548d --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java @@ -0,0 +1,152 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobLogReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * job log report helper + * + * @author xuxueli 2019-11-22 + */ +public class JobLogReportHelper { + private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class); + + private static JobLogReportHelper instance = new JobLogReportHelper(); + public static JobLogReportHelper getInstance(){ + return instance; + } + + + private Thread logrThread; + private volatile boolean toStop = false; + public void start(){ + logrThread = new Thread(new Runnable() { + + @Override + public void run() { + + // last clean log time + long lastCleanLogTime = 0; + + + while (!toStop) { + + // 1、log-report refresh: refresh log report in 3 days + try { + + for (int i = 0; i < 3; i++) { + + // today + Calendar itemDay = Calendar.getInstance(); + itemDay.add(Calendar.DAY_OF_MONTH, -i); + itemDay.set(Calendar.HOUR_OF_DAY, 0); + itemDay.set(Calendar.MINUTE, 0); + itemDay.set(Calendar.SECOND, 0); + itemDay.set(Calendar.MILLISECOND, 0); + + Date todayFrom = itemDay.getTime(); + + itemDay.set(Calendar.HOUR_OF_DAY, 23); + itemDay.set(Calendar.MINUTE, 59); + itemDay.set(Calendar.SECOND, 59); + itemDay.set(Calendar.MILLISECOND, 999); + + Date todayTo = itemDay.getTime(); + + // refresh log-report every minute + XxlJobLogReport xxlJobLogReport = new XxlJobLogReport(); + xxlJobLogReport.setTriggerDay(todayFrom); + xxlJobLogReport.setRunningCount(0); + xxlJobLogReport.setSucCount(0); + xxlJobLogReport.setFailCount(0); + + Map triggerCountMap = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLogReport(todayFrom, todayTo); + if (triggerCountMap!=null && triggerCountMap.size()>0) { + int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0; + int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0; + int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0; + int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; + + xxlJobLogReport.setRunningCount(triggerDayCountRunning); + xxlJobLogReport.setSucCount(triggerDayCountSuc); + xxlJobLogReport.setFailCount(triggerDayCountFail); + } + + // do refresh + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().update(xxlJobLogReport); + if (ret < 1) { + XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().save(xxlJobLogReport); + } + } + + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e); + } + } + + // 2、log-clean: switch open & once each day + if (XxlJobAdminConfig.getAdminConfig().getLogretentiondays()>0 + && System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000) { + + // expire-time + Calendar expiredDay = Calendar.getInstance(); + expiredDay.add(Calendar.DAY_OF_MONTH, -1 * XxlJobAdminConfig.getAdminConfig().getLogretentiondays()); + expiredDay.set(Calendar.HOUR_OF_DAY, 0); + expiredDay.set(Calendar.MINUTE, 0); + expiredDay.set(Calendar.SECOND, 0); + expiredDay.set(Calendar.MILLISECOND, 0); + Date clearBeforeTime = expiredDay.getTime(); + + // clean expired log + List logIds = null; + do { + logIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findClearLogIds(0, 0, clearBeforeTime, 0, 1000); + if (logIds!=null && logIds.size()>0) { + XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().clearLog(logIds); + } + } while (logIds!=null && logIds.size()>0); + + // update clean time + lastCleanLogTime = System.currentTimeMillis(); + } + + try { + TimeUnit.MINUTES.sleep(1); + } catch (Exception e) { + if (!toStop) { + logger.error(e.getMessage(), e); + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, job log report thread stop"); + + } + }); + logrThread.setDaemon(true); + logrThread.setName("xxl-job, admin JobLogReportHelper"); + logrThread.start(); + } + + public void toStop(){ + toStop = true; + // interrupt and wait + logrThread.interrupt(); + try { + logrThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java new file mode 100644 index 00000000..5f9fd724 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java @@ -0,0 +1,204 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobRegistry; +import com.xxl.job.core.biz.model.RegistryParam; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.RegistryConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.concurrent.*; + +/** + * job registry instance + * @author xuxueli 2016-10-02 19:10:24 + */ +public class JobRegistryHelper { + private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class); + + private static JobRegistryHelper instance = new JobRegistryHelper(); + public static JobRegistryHelper getInstance(){ + return instance; + } + + private ThreadPoolExecutor registryOrRemoveThreadPool = null; + private Thread registryMonitorThread; + private volatile boolean toStop = false; + + public void start(){ + + // for registry or remove + registryOrRemoveThreadPool = new ThreadPoolExecutor( + 2, + 10, + 30L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(2000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode()); + } + }, + new RejectedExecutionHandler() { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + r.run(); + logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now)."); + } + }); + + // for monitor + registryMonitorThread = new Thread(new Runnable() { + @Override + public void run() { + while (!toStop) { + try { + // auto registry group + List groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0); + if (groupList!=null && !groupList.isEmpty()) { + + // remove dead address (admin/executor) + List ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date()); + if (ids!=null && ids.size()>0) { + XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids); + } + + // fresh online address (admin/executor) + HashMap> appAddressMap = new HashMap>(); + List list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date()); + if (list != null) { + for (XxlJobRegistry item: list) { + if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) { + String appname = item.getRegistryKey(); + List registryList = appAddressMap.get(appname); + if (registryList == null) { + registryList = new ArrayList(); + } + + if (!registryList.contains(item.getRegistryValue())) { + registryList.add(item.getRegistryValue()); + } + appAddressMap.put(appname, registryList); + } + } + } + + // fresh group address + for (XxlJobGroup group: groupList) { + List registryList = appAddressMap.get(group.getAppname()); + String addressListStr = null; + if (registryList!=null && !registryList.isEmpty()) { + Collections.sort(registryList); + StringBuilder addressListSB = new StringBuilder(); + for (String item:registryList) { + addressListSB.append(item).append(","); + } + addressListStr = addressListSB.toString(); + addressListStr = addressListStr.substring(0, addressListStr.length()-1); + } + group.setAddressList(addressListStr); + group.setUpdateTime(new Date()); + + XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group); + } + } + } catch (Exception e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); + } + } + try { + TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT); + } catch (InterruptedException e) { + if (!toStop) { + logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e); + } + } + } + logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop"); + } + }); + registryMonitorThread.setDaemon(true); + registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread"); + registryMonitorThread.start(); + } + + public void toStop(){ + toStop = true; + + // stop registryOrRemoveThreadPool + registryOrRemoveThreadPool.shutdownNow(); + + // stop monitir (interrupt and wait) + registryMonitorThread.interrupt(); + try { + registryMonitorThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + + // ---------------------- helper ---------------------- + + public ReturnT registry(RegistryParam registryParam) { + + // valid + if (!StringUtils.hasText(registryParam.getRegistryGroup()) + || !StringUtils.hasText(registryParam.getRegistryKey()) + || !StringUtils.hasText(registryParam.getRegistryValue())) { + return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument."); + } + + // async execute + registryOrRemoveThreadPool.execute(new Runnable() { + @Override + public void run() { + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); + if (ret < 1) { + XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date()); + + // fresh + freshGroupRegistryInfo(registryParam); + } + } + }); + + return ReturnT.SUCCESS; + } + + public ReturnT registryRemove(RegistryParam registryParam) { + + // valid + if (!StringUtils.hasText(registryParam.getRegistryGroup()) + || !StringUtils.hasText(registryParam.getRegistryKey()) + || !StringUtils.hasText(registryParam.getRegistryValue())) { + return new ReturnT(ReturnT.FAIL_CODE, "Illegal Argument."); + } + + // async execute + registryOrRemoveThreadPool.execute(new Runnable() { + @Override + public void run() { + int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue()); + if (ret > 0) { + // fresh + freshGroupRegistryInfo(registryParam); + } + } + }); + + return ReturnT.SUCCESS; + } + + private void freshGroupRegistryInfo(RegistryParam registryParam){ + // Under consideration, prevent affecting core tables + } + + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java new file mode 100644 index 00000000..43405734 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java @@ -0,0 +1,368 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.cron.CronExpression; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum; +import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import io.sc.platform.core.Environment; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +public class JobScheduleHelper { + private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class); + + public static final long PRE_READ_MS = 5000; // pre read + private Thread scheduleThread; + private Thread ringThread; + private volatile boolean scheduleThreadToStop = false; + private volatile boolean ringThreadToStop = false; + private volatile static Map> ringData = new ConcurrentHashMap<>(); + + private static class JobScheduleHelperHolder{ + private static JobScheduleHelper instance =new JobScheduleHelper(); + } + + private JobScheduleHelper(){} + public static JobScheduleHelper getInstance(){ + return JobScheduleHelperHolder.instance; + } + + public void start(){ + // schedule thread + scheduleThread = new Thread(new Runnable() { + @Override + public void run() { + try { + TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis()%1000 ); + } catch (InterruptedException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + logger.info(">>>>>>>>> init xxl-job admin scheduler success."); + + // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20) + int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20; + + while (!scheduleThreadToStop) { + + // Scan Job + long start = System.currentTimeMillis(); + + Connection conn = null; + Boolean connAutoCommit = null; + PreparedStatement preparedStatement = null; + + boolean preReadSuc = true; + try { + + conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection(); + connAutoCommit = conn.getAutoCommit(); + conn.setAutoCommit(false); + + preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" ); + preparedStatement.execute(); + + // tx start + + // 1、pre read + long nowTime = System.currentTimeMillis(); + List scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount); + if (scheduleList!=null && scheduleList.size()>0) { + // 2、push time-ring + for (XxlJobInfo jobInfo: scheduleList) { + + // time-ring jump + if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) { + // 2.1、trigger-expire > 5s:pass && make next-trigger-time + logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId()); + + // 1、misfire match + MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING); + if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) { + // FIRE_ONCE_NOW 》 trigger + JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null); + logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); + } + + // 2、fresh next + refreshNextValidTime(jobInfo, new Date()); + + } else if (nowTime > jobInfo.getTriggerNextTime()) { + // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time + + // 1、trigger + JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null, null); + logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() ); + + // 2、fresh next + refreshNextValidTime(jobInfo, new Date()); + + // next-trigger-time in 5s, pre-read again + if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) { + + // 1、make ring second + int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); + + // 2、push time ring + pushTimeRing(ringSecond, jobInfo.getId()); + + // 3、fresh next + refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); + + } + + } else { + // 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time + + // 1、make ring second + int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60); + + // 2、push time ring + pushTimeRing(ringSecond, jobInfo.getId()); + + // 3、fresh next + refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime())); + + } + + } + + // 3、update trigger info + for (XxlJobInfo jobInfo: scheduleList) { + XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo); + } + + } else { + preReadSuc = false; + } + + // tx stop + + + } catch (Exception e) { + if (!scheduleThreadToStop) { + logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e); + } + } finally { + + // commit + if (conn != null) { + try { + conn.commit(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + try { + conn.setAutoCommit(connAutoCommit); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + try { + conn.close(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + + // close PreparedStatement + if (null != preparedStatement) { + try { + preparedStatement.close(); + } catch (SQLException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + } + long cost = System.currentTimeMillis()-start; + + + // Wait seconds, align second + if (cost < 1000) { // scan-overtime, not wait + try { + // pre-read period: success > scan each second; fail > skip this period; + TimeUnit.MILLISECONDS.sleep((preReadSuc?1000:PRE_READ_MS) - System.currentTimeMillis()%1000); + } catch (InterruptedException e) { + if (!scheduleThreadToStop) { + logger.error(e.getMessage(), e); + } + } + } + + } + + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop"); + } + }); + scheduleThread.setDaemon(true); + scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread"); + scheduleThread.start(); + + + // ring thread + ringThread = new Thread(new Runnable() { + @Override + public void run() { + + while (!ringThreadToStop) { + + // align second + try { + TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000); + } catch (InterruptedException e) { + if (!ringThreadToStop) { + logger.error(e.getMessage(), e); + } + } + + try { + // second data + List ringItemData = new ArrayList<>(); + int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验一个刻度; + for (int i = 0; i < 2; i++) { + List tmpData = ringData.remove( (nowSecond+60-i)%60 ); + if (tmpData != null) { + ringItemData.addAll(tmpData); + } + } + + // ring trigger + logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) ); + if (ringItemData.size() > 0) { + // do trigger + for (int jobId: ringItemData) { + // do trigger + JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null, null); + } + // clear + ringItemData.clear(); + } + } catch (Exception e) { + if (!ringThreadToStop) { + logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e); + } + } + } + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop"); + } + }); + ringThread.setDaemon(true); + ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread"); + ringThread.start(); + } + + private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { + Date nextValidTime = generateNextValidTime(jobInfo, fromTime); + if (nextValidTime != null) { + jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime()); + jobInfo.setTriggerNextTime(nextValidTime.getTime()); + } else { + jobInfo.setTriggerStatus(0); + jobInfo.setTriggerLastTime(0); + jobInfo.setTriggerNextTime(0); + logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}", + jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf()); + } + } + + private void pushTimeRing(int ringSecond, int jobId){ + // push async ring + List ringItemData = ringData.get(ringSecond); + if (ringItemData == null) { + ringItemData = new ArrayList(); + ringData.put(ringSecond, ringItemData); + } + ringItemData.add(jobId); + + logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) ); + } + + public void toStop(){ + + // 1、stop schedule + scheduleThreadToStop = true; + try { + TimeUnit.SECONDS.sleep(1); // wait + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + if (scheduleThread.getState() != Thread.State.TERMINATED){ + // interrupt and wait + scheduleThread.interrupt(); + try { + scheduleThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + // if has ring data + boolean hasRingData = false; + if (!ringData.isEmpty()) { + for (int second : ringData.keySet()) { + List tmpData = ringData.get(second); + if (tmpData!=null && tmpData.size()>0) { + hasRingData = true; + break; + } + } + } + if (hasRingData) { + try { + TimeUnit.SECONDS.sleep(8); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + // stop ring (wait job-in-memory stop) + ringThreadToStop = true; + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + if (ringThread.getState() != Thread.State.TERMINATED){ + // interrupt and wait + ringThread.interrupt(); + try { + ringThread.join(); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + } + + logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper stop"); + } + + + // ---------------------- tools ---------------------- + public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception { + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null); + if (ScheduleTypeEnum.CRON == scheduleTypeEnum) { + Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime); + return nextValidTime; + } else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) { + return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 ); + } + return null; + } + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java new file mode 100644 index 00000000..f71b96c8 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java @@ -0,0 +1,150 @@ +package io.sc.platform.job.core.thread; + +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.trigger.TriggerTypeEnum; +import com.xxl.job.admin.core.trigger.XxlJobTrigger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * job trigger thread pool helper + * + * @author xuxueli 2018-07-03 21:08:07 + */ +public class JobTriggerPoolHelper { + private static Logger logger = LoggerFactory.getLogger(JobTriggerPoolHelper.class); + + + // ---------------------- trigger pool ---------------------- + + // fast/slow thread pool + private ThreadPoolExecutor fastTriggerPool = null; + private ThreadPoolExecutor slowTriggerPool = null; + + public void start(){ + fastTriggerPool = new ThreadPoolExecutor( + 10, + XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(), + 60L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(1000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode()); + } + }); + + slowTriggerPool = new ThreadPoolExecutor( + 10, + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(), + 60L, + TimeUnit.SECONDS, + new LinkedBlockingQueue(2000), + new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode()); + } + }); + } + + + public void stop() { + //triggerPool.shutdown(); + fastTriggerPool.shutdownNow(); + slowTriggerPool.shutdownNow(); + logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success."); + } + + + // job timeout count + private volatile long minTim = System.currentTimeMillis()/60000; // ms > min + private volatile ConcurrentMap jobTimeoutCountMap = new ConcurrentHashMap<>(); + + + /** + * add trigger + */ + public void addTrigger(final int jobId, + final TriggerTypeEnum triggerType, + final int failRetryCount, + final String executorShardingParam, + final String executorParam, + final String addressList) { + + // choose thread pool + ThreadPoolExecutor triggerPool_ = fastTriggerPool; + AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId); + if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min + triggerPool_ = slowTriggerPool; + } + + // trigger + triggerPool_.execute(new Runnable() { + @Override + public void run() { + + long start = System.currentTimeMillis(); + + try { + // do trigger + XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } finally { + + // check timeout-count-map + long minTim_now = System.currentTimeMillis()/60000; + if (minTim != minTim_now) { + minTim = minTim_now; + jobTimeoutCountMap.clear(); + } + + // incr timeout-count-map + long cost = System.currentTimeMillis()-start; + if (cost > 500) { // ob-timeout threshold 500ms + AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1)); + if (timeoutCount != null) { + timeoutCount.incrementAndGet(); + } + } + + } + + } + }); + } + + + + // ---------------------- helper ---------------------- + + private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper(); + + public static void toStart() { + helper.start(); + } + public static void toStop() { + helper.stop(); + } + + /** + * @param jobId + * @param triggerType + * @param failRetryCount + * >=0: use this param + * <0: use param from job info config + * @param executorShardingParam + * @param executorParam + * null: use job param + * not null: cover job param + */ + public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) { + helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList); + } + +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java new file mode 100644 index 00000000..6400abba --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java @@ -0,0 +1,53 @@ +package io.sc.platform.job.core.vo; + +import io.sc.platform.orm.api.vo.BaseVo; + +import java.util.Date; + +public class ExecutorRegistryVo extends BaseVo { + private String id; + private String registryGroup; + private String registryKey; + private String registryValue; + private Date updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getRegistryGroup() { + return registryGroup; + } + + public void setRegistryGroup(String registryGroup) { + this.registryGroup = registryGroup; + } + + public String getRegistryKey() { + return registryKey; + } + + public void setRegistryKey(String registryKey) { + this.registryKey = registryKey; + } + + public String getRegistryValue() { + return registryValue; + } + + public void setRegistryValue(String registryValue) { + this.registryValue = registryValue; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java new file mode 100644 index 00000000..c7282bf9 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java @@ -0,0 +1,63 @@ +package io.sc.platform.job.core.vo; + +import io.sc.platform.job.core.enums.ExecutorAddressType; +import io.sc.platform.orm.api.vo.CorporationAuditorVo; + +import java.util.Set; + +public class ExecutorVo extends CorporationAuditorVo { + private String id; + private String appName; + private String name; + private String description; + private ExecutorAddressType addressType; + private Set addresses; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ExecutorAddressType getAddressType() { + return addressType; + } + + public void setAddressType(ExecutorAddressType addressType) { + this.addressType = addressType; + } + + public Set getAddresses() { + return addresses; + } + + public void setAddresses(Set addresses) { + this.addresses = addresses; + } +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java new file mode 100644 index 00000000..f7f42c2f --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java @@ -0,0 +1,62 @@ +package io.sc.platform.job.core.vo; + +import io.sc.platform.orm.api.vo.BaseVo; + +import java.util.Date; + +public class TaskLogReportVo extends BaseVo { + private String id; + private Date triggerDay; + private int runningCount; + private int sucCount; + private int failCount; + private Date updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Date getTriggerDay() { + return triggerDay; + } + + public void setTriggerDay(Date triggerDay) { + this.triggerDay = triggerDay; + } + + public int getRunningCount() { + return runningCount; + } + + public void setRunningCount(int runningCount) { + this.runningCount = runningCount; + } + + public int getSucCount() { + return sucCount; + } + + public void setSucCount(int sucCount) { + this.sucCount = sucCount; + } + + public int getFailCount() { + return failCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java new file mode 100644 index 00000000..40114ec1 --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java @@ -0,0 +1,143 @@ +package io.sc.platform.job.core.vo; + +import io.sc.platform.orm.api.vo.BaseVo; + +import java.util.Date; + +public class TaskLogVo extends BaseVo { + private String id; + private String executorId; + private String taskId; + private String executorAddress; + private String executorHandler; + private String executorParam; + private String executorShardingParam; + private int executorFailRetryCount; + private Date triggerTime; + private int triggerCode; + private String triggerMsg; + private Date handleTime; + private int handleCode; + private String handleMsg; + private int alarmStatus; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getExecutorId() { + return executorId; + } + + public void setExecutorId(String executorId) { + this.executorId = executorId; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getExecutorAddress() { + return executorAddress; + } + + public void setExecutorAddress(String executorAddress) { + this.executorAddress = executorAddress; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public String getExecutorShardingParam() { + return executorShardingParam; + } + + public void setExecutorShardingParam(String executorShardingParam) { + this.executorShardingParam = executorShardingParam; + } + + public int getExecutorFailRetryCount() { + return executorFailRetryCount; + } + + public void setExecutorFailRetryCount(int executorFailRetryCount) { + this.executorFailRetryCount = executorFailRetryCount; + } + + public Date getTriggerTime() { + return triggerTime; + } + + public void setTriggerTime(Date triggerTime) { + this.triggerTime = triggerTime; + } + + public int getTriggerCode() { + return triggerCode; + } + + public void setTriggerCode(int triggerCode) { + this.triggerCode = triggerCode; + } + + public String getTriggerMsg() { + return triggerMsg; + } + + public void setTriggerMsg(String triggerMsg) { + this.triggerMsg = triggerMsg; + } + + public Date getHandleTime() { + return handleTime; + } + + public void setHandleTime(Date handleTime) { + this.handleTime = handleTime; + } + + public int getHandleCode() { + return handleCode; + } + + public void setHandleCode(int handleCode) { + this.handleCode = handleCode; + } + + public String getHandleMsg() { + return handleMsg; + } + + public void setHandleMsg(String handleMsg) { + this.handleMsg = handleMsg; + } + + public int getAlarmStatus() { + return alarmStatus; + } + + public void setAlarmStatus(int alarmStatus) { + this.alarmStatus = alarmStatus; + } +} diff --git a/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java new file mode 100644 index 00000000..b9f6e99a --- /dev/null +++ b/io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java @@ -0,0 +1,189 @@ +package io.sc.platform.job.core.vo; + +import io.sc.platform.job.core.enums.*; +import io.sc.platform.orm.api.vo.CorporationAuditorVo; + +import java.util.Set; + +public class TaskVo extends CorporationAuditorVo { + private String id; + private String name; + private String description; + private String executor; + private String alarmEmail; + private TaskScheduleType scheduleType; + private String scheduleConf; + private ExpirationPolicy expirationPolicy; + private ExecutorRouteStrategy routeStrategy; + private String executorHandler; + private String executorParam; + private BlockStrategy blockStrategy; + private int timeout; + private int failRetryCount; + private GlueType glueType; + private String glueSource; + private String parent; + private TriggerStatus triggerStatus; + private long triggerLastTime; + private long triggerNextTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getExecutor() { + return executor; + } + + public void setExecutor(String executor) { + this.executor = executor; + } + + public String getAlarmEmail() { + return alarmEmail; + } + + public void setAlarmEmail(String alarmEmail) { + this.alarmEmail = alarmEmail; + } + + public TaskScheduleType getScheduleType() { + return scheduleType; + } + + public void setScheduleType(TaskScheduleType scheduleType) { + this.scheduleType = scheduleType; + } + + public String getScheduleConf() { + return scheduleConf; + } + + public void setScheduleConf(String scheduleConf) { + this.scheduleConf = scheduleConf; + } + + public ExpirationPolicy getExpirationPolicy() { + return expirationPolicy; + } + + public void setExpirationPolicy(ExpirationPolicy expirationPolicy) { + this.expirationPolicy = expirationPolicy; + } + + public ExecutorRouteStrategy getRouteStrategy() { + return routeStrategy; + } + + public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) { + this.routeStrategy = routeStrategy; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public BlockStrategy getBlockStrategy() { + return blockStrategy; + } + + public void setBlockStrategy(BlockStrategy blockStrategy) { + this.blockStrategy = blockStrategy; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getFailRetryCount() { + return failRetryCount; + } + + public void setFailRetryCount(int failRetryCount) { + this.failRetryCount = failRetryCount; + } + + public GlueType getGlueType() { + return glueType; + } + + public void setGlueType(GlueType glueType) { + this.glueType = glueType; + } + + public String getGlueSource() { + return glueSource; + } + + public void setGlueSource(String glueSource) { + this.glueSource = glueSource; + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public TriggerStatus getTriggerStatus() { + return triggerStatus; + } + + public void setTriggerStatus(TriggerStatus triggerStatus) { + this.triggerStatus = triggerStatus; + } + + public long getTriggerLastTime() { + return triggerLastTime; + } + + public void setTriggerLastTime(long triggerLastTime) { + this.triggerLastTime = triggerLastTime; + } + + public long getTriggerNextTime() { + return triggerNextTime; + } + + public void setTriggerNextTime(long triggerNextTime) { + this.triggerNextTime = triggerNextTime; + } +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorEntity.java similarity index 55% rename from io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java rename to io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorEntity.java index 40e010c9..fc75b82c 100644 --- a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorEntity.java @@ -1,15 +1,18 @@ package io.sc.platform.job.manager.jpa.entity; import io.sc.platform.job.core.enums.ExecutorAddressType; +import io.sc.platform.job.core.vo.ExecutorVo; import io.sc.platform.orm.converter.SetStringConverter; +import io.sc.platform.orm.entity.CorporationAuditorEntity; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import javax.validation.constraints.Size; -import java.util.Date; import java.util.Set; -public class JobGroupEntity { +@Entity +@Table(name="JOB_EXECUTOR") +public class ExecutorEntity extends CorporationAuditorEntity { //主键 @Id @GeneratedValue(generator = "system-uuid") @@ -18,25 +21,41 @@ public class JobGroupEntity { @Size(max=36) private String id; - @Column(name="APP_NAME", length=255) + //应用名称 + @Column(name="APP_NAME_", length=255) @Size(min=1,max=255) private String appName; - @Column(name="TITLE", length=255) + //名称 + @Column(name="NAME_", length=255) @Size(min=1,max=255) - private String title; + private String name; - @Column(name="ADDRESS_TYPE") + //描述 + @Column(name="DESCRIPTION_", length=255) + @Size(max=255) + private String description; + + //地址类型 + @Column(name="ADDRESS_TYPE_") @Enumerated(EnumType.STRING) private ExecutorAddressType addressType; - @Column(name="ADDRESS_LIST") + //地址列表 + @Column(name="ADDRESS_LIST_") @Convert(converter = SetStringConverter.class) private Set addresses; - @Column(name="UPDATE_TIME") - @Temporal(TemporalType.TIMESTAMP) - private Date updateTime; + @Override + public ExecutorVo toVo() { + ExecutorVo vo =new ExecutorVo(); + CorporationAuditorEntity.toVo(vo,this); + vo.setId(this.getId()); + vo.setAppName(this.getAppName()); + vo.setName(this.getName()); + vo.setDescription(this.getDescription()); + return vo; + } public String getId() { return id; @@ -54,12 +73,20 @@ public class JobGroupEntity { this.appName = appName; } - public String getTitle() { - return title; + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; } - public void setTitle(String title) { - this.title = title; + public void setDescription(String description) { + this.description = description; } public ExecutorAddressType getAddressType() { @@ -77,12 +104,4 @@ public class JobGroupEntity { public void setAddresses(Set addresses) { this.addresses = addresses; } - - public Date getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } } diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java new file mode 100644 index 00000000..a83ff37c --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java @@ -0,0 +1,91 @@ +package io.sc.platform.job.manager.jpa.entity; + +import io.sc.platform.job.core.vo.ExecutorRegistryVo; +import io.sc.platform.orm.entity.BaseEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.util.Date; + +@Entity +@Table(name="JOB_EXECUTOR") +public class ExecutorRegistryEntity extends BaseEntity { + //主键 + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "uuid2") + @Column(name="ID_", length=36) + @Size(max=36) + private String id; + + //名称 + @Column(name="REGISTRY_GROUP_", length=255) + @Size(max=255) + private String registryGroup; + + //名称 + @Column(name="REGISTRY_KEY_", length=255) + @Size(max=255) + private String registryKey; + + //名称 + @Column(name="REGISTRY_VALUE_", length=255) + @Size(max=255) + private String registryValue; + + @Column(name="UPDATE_TIME_") + @Temporal(TemporalType.TIMESTAMP) + private Date updateTime; + + @Override + public ExecutorRegistryVo toVo() { + ExecutorRegistryVo vo =new ExecutorRegistryVo(); + vo.setId(this.getId()); + vo.setRegistryGroup(this.getRegistryGroup()); + vo.setRegistryKey(this.getRegistryKey()); + vo.setRegistryValue(this.getRegistryValue()); + vo.setUpdateTime(this.getUpdateTime()); + return vo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getRegistryGroup() { + return registryGroup; + } + + public void setRegistryGroup(String registryGroup) { + this.registryGroup = registryGroup; + } + + public String getRegistryKey() { + return registryKey; + } + + public void setRegistryKey(String registryKey) { + this.registryKey = registryKey; + } + + public String getRegistryValue() { + return registryValue; + } + + public void setRegistryValue(String registryValue) { + this.registryValue = registryValue; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java new file mode 100644 index 00000000..9b46de8a --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java @@ -0,0 +1,299 @@ +package io.sc.platform.job.manager.jpa.entity; + +import io.sc.platform.job.core.enums.*; +import io.sc.platform.job.core.vo.TaskVo; +import io.sc.platform.orm.entity.CorporationAuditorEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import javax.validation.constraints.Size; + +@Entity +@Table(name="JOB_TASK") +public class TaskEntity extends CorporationAuditorEntity { + //主键 + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "uuid2") + @Column(name="ID_", length=36) + @Size(max=36) + private String id; + + //名称 + @Column(name="NAME_", length=255) + @Size(min=1,max=255) + private String name; + + //描述 + @Column(name="DESCRIPTION_", length=255) + @Size(max=255) + private String description; + + //执行器 + @ManyToOne(fetch= FetchType.LAZY) + @JoinColumn(name="EXECUTOR_ID_") + private ExecutorEntity executor; + + //报警邮件 + @Column(name="ALARM_EMAIL_", length=255) + @Size(max=255) + private String alarmEmail; + + //调度类型 + @Column(name="SCHEDULE_TYPE_") + @Enumerated(EnumType.STRING) + private TaskScheduleType scheduleType; + + //调度配置,值含义取决于调度类型 + @Column(name="SCHEDULE_CONF_", length=255) + @Size(max=255) + private String scheduleConf; + + + //调度过期策略 + @Column(name="EXPIRATION_POLICY_") + @Enumerated(EnumType.STRING) + private ExpirationPolicy expirationPolicy; + + //执行器路由策略 + @Column(name="ROUTE_STRATEGY_") + @Enumerated(EnumType.STRING) + private ExecutorRouteStrategy routeStrategy; + + //执行器,任务Handler名称 + @Column(name="EXECUTOR_HANDLER_", length=255) + @Size(max=255) + private String executorHandler; + + //执行器,任务参数 + @Column(name="EXECUTOR_PARAM_", length=255) + @Size(max=255) + private String executorParam; + + //阻塞处理策略 + @Column(name="BLOCK_STRATEGY_") + @Enumerated(EnumType.STRING) + private BlockStrategy blockStrategy; + + //任务执行超时时间,单位秒 + @Column(name="TIMEOUT_") + private int timeout; + + //失败重试次数 + @Column(name="FAIL_RETRY_COUNT_") + private int failRetryCount; + + //GLUE类型 + @Column(name="GLUE_TYPE_") + @Enumerated(EnumType.STRING) + private GlueType glueType; + + //GLUE源代码 + @Column(name="GLUE_SOURCE_") + private String glueSource; + + //父任务 + @ManyToOne(fetch=FetchType.LAZY) + @JoinColumn(name="PARENT_ID_") + private TaskEntity parent; + + //调度状态 + @Column(name="TRIGGER_STATUS_") + @Enumerated(EnumType.STRING) + private TriggerStatus triggerStatus; + + //上次调度时间 + @Column(name="TRIGGER_LAST_TIME_") + private long triggerLastTime; + + //下次调度时间 + @Column(name="TRIGGER_NEXT_TIME_") + private long triggerNextTime; + + @Override + public TaskVo toVo() { + TaskVo vo =new TaskVo(); + CorporationAuditorEntity.toVo(vo,this); + vo.setId(this.getId()); + vo.setName(this.getName()); + vo.setDescription(this.getDescription()); + vo.setExecutor(this.getExecutor()==null?null:this.getExecutor().getId()); + vo.setAlarmEmail(this.getAlarmEmail()); + vo.setScheduleType(this.getScheduleType()); + vo.setScheduleConf(this.getScheduleConf()); + vo.setExpirationPolicy(this.getExpirationPolicy()); + vo.setRouteStrategy(this.getRouteStrategy()); + vo.setExecutorHandler(this.getExecutorHandler()); + vo.setExecutorParam(this.getExecutorParam()); + vo.setBlockStrategy(this.getBlockStrategy()); + vo.setTimeout(this.getTimeout()); + vo.setFailRetryCount(this.getFailRetryCount()); + vo.setGlueType(this.getGlueType()); + vo.setGlueSource(this.getGlueSource()); + vo.setParent(this.getParent()==null?null:this.getParent().getId()); + vo.setTriggerStatus(this.getTriggerStatus()); + vo.setTriggerLastTime(this.getTriggerLastTime()); + vo.setTriggerNextTime(this.getTriggerNextTime()); + return vo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ExecutorEntity getExecutor() { + return executor; + } + + public void setExecutor(ExecutorEntity executor) { + this.executor = executor; + } + + public String getAlarmEmail() { + return alarmEmail; + } + + public void setAlarmEmail(String alarmEmail) { + this.alarmEmail = alarmEmail; + } + + public TaskScheduleType getScheduleType() { + return scheduleType; + } + + public void setScheduleType(TaskScheduleType scheduleType) { + this.scheduleType = scheduleType; + } + + public String getScheduleConf() { + return scheduleConf; + } + + public void setScheduleConf(String scheduleConf) { + this.scheduleConf = scheduleConf; + } + + public ExpirationPolicy getExpirationPolicy() { + return expirationPolicy; + } + + public void setExpirationPolicy(ExpirationPolicy expirationPolicy) { + this.expirationPolicy = expirationPolicy; + } + + public ExecutorRouteStrategy getRouteStrategy() { + return routeStrategy; + } + + public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) { + this.routeStrategy = routeStrategy; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public BlockStrategy getBlockStrategy() { + return blockStrategy; + } + + public void setBlockStrategy(BlockStrategy blockStrategy) { + this.blockStrategy = blockStrategy; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getFailRetryCount() { + return failRetryCount; + } + + public void setFailRetryCount(int failRetryCount) { + this.failRetryCount = failRetryCount; + } + + public GlueType getGlueType() { + return glueType; + } + + public void setGlueType(GlueType glueType) { + this.glueType = glueType; + } + + public String getGlueSource() { + return glueSource; + } + + public void setGlueSource(String glueSource) { + this.glueSource = glueSource; + } + + public TaskEntity getParent() { + return parent; + } + + public void setParent(TaskEntity parent) { + this.parent = parent; + } + + public TriggerStatus getTriggerStatus() { + return triggerStatus; + } + + public void setTriggerStatus(TriggerStatus triggerStatus) { + this.triggerStatus = triggerStatus; + } + + public long getTriggerLastTime() { + return triggerLastTime; + } + + public void setTriggerLastTime(long triggerLastTime) { + this.triggerLastTime = triggerLastTime; + } + + public long getTriggerNextTime() { + return triggerNextTime; + } + + public void setTriggerNextTime(long triggerNextTime) { + this.triggerNextTime = triggerNextTime; + } +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java new file mode 100644 index 00000000..3c0749c7 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java @@ -0,0 +1,230 @@ +package io.sc.platform.job.manager.jpa.entity; + +import io.sc.platform.job.core.vo.TaskLogVo; +import io.sc.platform.job.core.vo.TaskVo; +import io.sc.platform.orm.entity.BaseEntity; +import io.sc.platform.orm.entity.CorporationAuditorEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.util.Date; + +@Entity +@Table(name="JOB_TASK_LOG") +public class TaskLogEntity extends BaseEntity { + //主键 + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "uuid2") + @Column(name="ID_", length=36) + @Size(max=36) + private String id; + + //执行器ID + @Column(name="EXECUTOR_ID_", length=36) + private String executorId; + + //任务ID + @Column(name="TASK_ID_", length=36) + private String taskId; + + // execute info + //执行器地址,本次执行的地址 + @Column(name="EXECUTOR_ADDRESS_", length=255) + @Size(max=255) + private String executorAddress; + + //执行器任务handler + @Column(name="EXECUTOR_HANDLER_", length=255) + @Size(max=255) + private String executorHandler; + + //执行器任务参数 + @Column(name="EXECUTOR_PARAM_", length=255) + @Size(max=255) + private String executorParam; + + //执行器任务分片参数,格式如 1/2 + @Column(name="EXECUTOR_SHARDING_PARAM_", length=20) + @Size(max=20) + private String executorShardingParam; + + //失败重试次数 + @Column(name="EXECUTOR_FAIL_RETRY_COUNT_") + private int executorFailRetryCount; + + // trigger info + //调度-时间 + @Column(name="TRIGGER_TIME_") + @Temporal(TemporalType.TIMESTAMP) + private Date triggerTime; + + //调度-结果 + @Column(name="TRIGGER_CODE_") + private int triggerCode; + + //调度-日志 + @Column(name="TRIGGER_MSG_") + private String triggerMsg; + + // handle info + //执行-时间 + @Column(name="HANDLE_TIME_") + @Temporal(TemporalType.TIMESTAMP) + private Date handleTime; + + //执行-状态 + @Column(name="HANDLE_CODE_") + private int handleCode; + + //执行-日志 + @Column(name="HANDLE_MSG_") + private String handleMsg; + + // alarm info + //告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败 + @Column(name="ALARM_STATUS_") + private int alarmStatus; + + @Override + public TaskLogVo toVo() { + TaskLogVo vo =new TaskLogVo(); + vo.setId(this.getId()); + vo.setExecutorId(this.getExecutorId()); + vo.setTaskId(this.getTaskId()); + vo.setExecutorAddress(this.getExecutorAddress()); + vo.setExecutorHandler(this.getExecutorHandler()); + vo.setExecutorParam(this.getExecutorParam()); + vo.setExecutorShardingParam(this.getExecutorShardingParam()); + vo.setExecutorFailRetryCount(this.getExecutorFailRetryCount()); + vo.setTriggerTime(this.getTriggerTime()); + vo.setTriggerCode(this.getTriggerCode()); + vo.setTriggerMsg(this.getTriggerMsg()); + vo.setHandleTime(this.getHandleTime()); + vo.setHandleCode(this.getHandleCode()); + vo.setHandleMsg(this.getHandleMsg()); + vo.setAlarmStatus(this.getAlarmStatus()); + return vo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getExecutorId() { + return executorId; + } + + public void setExecutorId(String executorId) { + this.executorId = executorId; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getExecutorAddress() { + return executorAddress; + } + + public void setExecutorAddress(String executorAddress) { + this.executorAddress = executorAddress; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public String getExecutorShardingParam() { + return executorShardingParam; + } + + public void setExecutorShardingParam(String executorShardingParam) { + this.executorShardingParam = executorShardingParam; + } + + public int getExecutorFailRetryCount() { + return executorFailRetryCount; + } + + public void setExecutorFailRetryCount(int executorFailRetryCount) { + this.executorFailRetryCount = executorFailRetryCount; + } + + public Date getTriggerTime() { + return triggerTime; + } + + public void setTriggerTime(Date triggerTime) { + this.triggerTime = triggerTime; + } + + public int getTriggerCode() { + return triggerCode; + } + + public void setTriggerCode(int triggerCode) { + this.triggerCode = triggerCode; + } + + public String getTriggerMsg() { + return triggerMsg; + } + + public void setTriggerMsg(String triggerMsg) { + this.triggerMsg = triggerMsg; + } + + public Date getHandleTime() { + return handleTime; + } + + public void setHandleTime(Date handleTime) { + this.handleTime = handleTime; + } + + public int getHandleCode() { + return handleCode; + } + + public void setHandleCode(int handleCode) { + this.handleCode = handleCode; + } + + public String getHandleMsg() { + return handleMsg; + } + + public void setHandleMsg(String handleMsg) { + this.handleMsg = handleMsg; + } + + public int getAlarmStatus() { + return alarmStatus; + } + + public void setAlarmStatus(int alarmStatus) { + this.alarmStatus = alarmStatus; + } +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java new file mode 100644 index 00000000..c80b4bd1 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java @@ -0,0 +1,99 @@ +package io.sc.platform.job.manager.jpa.entity; + +import io.sc.platform.job.core.vo.TaskLogReportVo; +import io.sc.platform.job.core.vo.TaskLogVo; +import io.sc.platform.orm.entity.BaseEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.util.Date; + +@Entity +@Table(name="JOB_TASK_LOG_REPORT") +public class TaskLogReportEntity extends BaseEntity { + //主键 + @Id + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "uuid2") + @Column(name="ID_", length=36) + @Size(max=36) + private String id; + + @Column(name="TRIGGER_DAY_") + @Temporal(TemporalType.TIMESTAMP) + private Date triggerDay; + + @Column(name="RUNNING_COUNT_") + private int runningCount; + + @Column(name="SUC_COUNT_") + private int sucCount; + + @Column(name="FAIL_COUNT_") + private int failCount; + + @Column(name="UPDATE_TIME_") + @Temporal(TemporalType.TIMESTAMP) + private Date updateTime; + + @Override + public TaskLogReportVo toVo() { + TaskLogReportVo vo =new TaskLogReportVo(); + vo.setId(this.getId()); + vo.setTriggerDay(this.getTriggerDay()); + vo.setRunningCount(this.getRunningCount()); + vo.setSucCount(this.getSucCount()); + vo.setFailCount(this.getFailCount()); + vo.setUpdateTime(this.getUpdateTime()); + return vo; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Date getTriggerDay() { + return triggerDay; + } + + public void setTriggerDay(Date triggerDay) { + this.triggerDay = triggerDay; + } + + public int getRunningCount() { + return runningCount; + } + + public void setRunningCount(int runningCount) { + this.runningCount = runningCount; + } + + public int getSucCount() { + return sucCount; + } + + public void setSucCount(int sucCount) { + this.sucCount = sucCount; + } + + public int getFailCount() { + return failCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java new file mode 100644 index 00000000..fbf39f33 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java @@ -0,0 +1,12 @@ +package io.sc.platform.job.manager.jpa.repository; + +import io.sc.platform.job.core.enums.ExecutorAddressType; +import io.sc.platform.job.manager.jpa.entity.ExecutorEntity; +import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity; +import io.sc.platform.orm.repository.DaoRepository; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface ExecutorRegistryRepository extends DaoRepository { +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRepository.java similarity index 57% rename from io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java rename to io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRepository.java index a90ceb6a..9d12593a 100644 --- a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRepository.java @@ -1,12 +1,12 @@ package io.sc.platform.job.manager.jpa.repository; import io.sc.platform.job.core.enums.ExecutorAddressType; -import io.sc.platform.job.manager.jpa.entity.JobGroupEntity; +import io.sc.platform.job.manager.jpa.entity.ExecutorEntity; import io.sc.platform.orm.repository.DaoRepository; import org.springframework.data.repository.query.Param; import java.util.List; -public interface JobGroupRepository extends DaoRepository { - public List findByAddressType(@Param("addressType") ExecutorAddressType addressType); +public interface ExecutorRepository extends DaoRepository { + public List findByAddressType(@Param("addressType") ExecutorAddressType addressType); } diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java new file mode 100644 index 00000000..29a0c96e --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java @@ -0,0 +1,8 @@ +package io.sc.platform.job.manager.jpa.repository; + +import io.sc.platform.job.manager.jpa.entity.TaskLogEntity; +import io.sc.platform.job.manager.jpa.entity.TaskLogReportEntity; +import io.sc.platform.orm.repository.DaoRepository; + +public interface TaskLogReportRepository extends DaoRepository { +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java new file mode 100644 index 00000000..238008fe --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java @@ -0,0 +1,7 @@ +package io.sc.platform.job.manager.jpa.repository; + +import io.sc.platform.job.manager.jpa.entity.TaskLogEntity; +import io.sc.platform.orm.repository.DaoRepository; + +public interface TaskLogRepository extends DaoRepository { +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java new file mode 100644 index 00000000..e3b32f43 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java @@ -0,0 +1,8 @@ +package io.sc.platform.job.manager.jpa.repository; + +import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity; +import io.sc.platform.job.manager.jpa.entity.TaskEntity; +import io.sc.platform.orm.repository.DaoRepository; + +public interface TaskRepository extends DaoRepository { +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java new file mode 100644 index 00000000..97d687a2 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java @@ -0,0 +1,10 @@ +package io.sc.platform.job.manager.service; + +import io.sc.platform.job.manager.jpa.entity.TaskEntity; +import io.sc.platform.job.manager.jpa.repository.TaskRepository; +import io.sc.platform.orm.service.DaoService; + +public interface TaskService extends DaoService { + public void start(int id); + public void stop(int id); +} diff --git a/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java new file mode 100644 index 00000000..ad033808 --- /dev/null +++ b/io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java @@ -0,0 +1,58 @@ +package io.sc.platform.job.manager.service.impl; + +import io.sc.platform.job.core.enums.TaskScheduleType; +import io.sc.platform.job.manager.jpa.entity.TaskEntity; +import io.sc.platform.job.manager.jpa.repository.TaskRepository; +import io.sc.platform.job.manager.service.TaskService; +import io.sc.platform.orm.service.impl.DaoServiceImpl; + +import java.util.Date; + +public class TaskServiceImpl extends DaoServiceImpl implements TaskService { + @Override + public void start(String id) { + TaskEntity taskEntity =this.findById(id); + if(taskEntity==null){ + return; + } + if(TaskScheduleType.NONE.equals(taskEntity.getScheduleType())){ + throw new RuntimeException(); + } + long nextTriggerTime = 0; + + + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + + // valid + ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE); + if (ScheduleTypeEnum.NONE == scheduleTypeEnum) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")) ); + } + + // next trigger time (5s后生效,避开预读周期) + long nextTriggerTime = 0; + try { + Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS)); + if (nextValidTime == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); + } + nextTriggerTime = nextValidTime.getTime(); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) ); + } + + xxlJobInfo.setTriggerStatus(1); + xxlJobInfo.setTriggerLastTime(0); + xxlJobInfo.setTriggerNextTime(nextTriggerTime); + + xxlJobInfo.setUpdateTime(new Date()); + xxlJobInfoDao.update(xxlJobInfo); + return ReturnT.SUCCESS; + } + + @Override + public void stop(int id) { + + } +} diff --git a/io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml b/io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml index 11e6924f..12f866bd 100644 --- a/io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml +++ b/io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml @@ -17,7 +17,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/io.sc.platform.lcdp.frontend/package.json b/io.sc.platform.lcdp.frontend/package.json index ce492570..cc5c1e53 100644 --- a/io.sc.platform.lcdp.frontend/package.json +++ b/io.sc.platform.lcdp.frontend/package.json @@ -1,6 +1,6 @@ { "name": "io.sc.platform.lcdp.frontend", - "version": "8.1.19", + "version": "8.1.20", "description": "", "private": false, "keywords": [ @@ -92,7 +92,7 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.45", + "platform-core": "8.1.47", "quasar": "2.13.0", "tailwindcss": "3.3.5", "vue": "3.3.7", diff --git a/io.sc.platform.mvc.frontend/package.json b/io.sc.platform.mvc.frontend/package.json index 90ca8a96..27417473 100644 --- a/io.sc.platform.mvc.frontend/package.json +++ b/io.sc.platform.mvc.frontend/package.json @@ -1,6 +1,6 @@ { "name": "io.sc.platform.mvc.frontend", - "version": "8.1.19", + "version": "8.1.20", "description": "", "private": false, "keywords": [ @@ -79,7 +79,7 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.45", + "platform-core": "8.1.47", "quasar": "2.13.0", "tailwindcss": "3.3.5", "vue": "3.3.7", diff --git a/io.sc.platform.security.frontend/package.json b/io.sc.platform.security.frontend/package.json index f47fa4d8..f24ee915 100644 --- a/io.sc.platform.security.frontend/package.json +++ b/io.sc.platform.security.frontend/package.json @@ -1,6 +1,6 @@ { "name": "io.sc.platform.security.frontend", - "version": "8.1.19", + "version": "8.1.20", "description": "", "private": false, "keywords": [ @@ -79,7 +79,7 @@ "luckyexcel": "1.0.1", "mockjs": "1.1.0", "pinia": "2.1.7", - "platform-core": "8.1.45", + "platform-core": "8.1.47", "quasar": "2.13.0", "tailwindcss": "3.3.5", "vue": "3.3.7", diff --git a/io.sc.platform.system.frontend/package.json b/io.sc.platform.system.frontend/package.json index 48bf365d..8ea209d2 100644 --- a/io.sc.platform.system.frontend/package.json +++ b/io.sc.platform.system.frontend/package.json @@ -1,6 +1,6 @@ { "name": "io.sc.platform.system.frontend", - "version": "8.1.19", + "version": "8.1.20", "description": "", "private": false, "keywords": [ diff --git a/io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java b/io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java index 1e5bc1d0..297f702b 100644 --- a/io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java +++ b/io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java @@ -22,7 +22,6 @@ import java.util.Set; */ @Entity @Table(name="SYS_ROLE") -@JsonSerialize(using = RoleEntityJsonSerializer.class) public class RoleEntity extends CorporationAuditorEntity { //主键 @Id