43 changed files with 3000 additions and 106 deletions
@ -0,0 +1,53 @@ |
|||
<template> |
|||
<q-tr> |
|||
<q-td v-for="(col, index) in cols" :key="col.name" :style="{ 'padding-left': index == 0 ? '2px' : '7px' }"> |
|||
<div class="flex flex-nowrap items-center"> |
|||
<template v-if="index == 0"> |
|||
<!--层级占位符--> |
|||
<span :style="`width:${27 * props.level}px;`"></span> |
|||
<!--展开按钮--> |
|||
<q-btn |
|||
v-if="data.children && data.children.length > 0" |
|||
flat |
|||
size="16px" |
|||
dense |
|||
padding="0px 0px" |
|||
:icon="data.expand ? 'bi-dash' : 'bi-plus'" |
|||
@click="data.expand = !data.expand" |
|||
/> |
|||
<!--展开按钮占位符--> |
|||
<span v-else style="width: 27px"></span> |
|||
<!--选择框--> |
|||
<q-checkbox v-model="data.selected" flat size="40px" dense /> |
|||
<!--文件夹图标--> |
|||
<q-icon v-if="data.children && data.children.length > 0" name="sym_o_folder_open" size="20px" class="px-1"></q-icon> |
|||
<!--文件图标--> |
|||
<q-icon v-else name="bi-file-earmark" size="16px" class="px-1"></q-icon> |
|||
</template> |
|||
<div v-dompurify-html="col.format ? col.format(data[col.name], data) : col.value"></div> |
|||
</div> |
|||
</q-td> |
|||
</q-tr> |
|||
<template v-for="child in data.children" :key="child.id"> |
|||
<TableRow v-if="data.expand" :cols="cols" :data="child" :level="props.level + 1"></TableRow> |
|||
</template> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const props = defineProps({ |
|||
level: { type: Number, default: 0 }, |
|||
cols: { |
|||
type: Array, |
|||
default: () => { |
|||
return []; |
|||
}, |
|||
}, |
|||
data: { |
|||
type: Array, |
|||
default: () => { |
|||
return []; |
|||
}, |
|||
}, |
|||
}); |
|||
const cols = props.cols; |
|||
const data = props.data; |
|||
</script> |
@ -1,53 +1,54 @@ |
|||
<template> |
|||
<div> |
|||
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> |
|||
</div> |
|||
<w-list-grid |
|||
:tree="true" |
|||
title="User List" |
|||
:no-action-icon="true" |
|||
:target-object-name="$t('菜单')" |
|||
:actions="[ |
|||
'query', |
|||
'refresh', |
|||
'expandAll', |
|||
'selectAll', |
|||
'separator', |
|||
'add', |
|||
'clone', |
|||
'edit', |
|||
'remove', |
|||
'removeAll', |
|||
'separator', |
|||
'detail', |
|||
|
|||
'addTop', |
|||
'addChild', |
|||
]" |
|||
:columns="columns" |
|||
:auto-fetch-data="true" |
|||
:data-url="Environment.apiContextPath('/api/system/menu/allMenus')" |
|||
></w-list-grid> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { ref, onMounted, toRaw } from 'vue'; |
|||
import { useRoute } from 'vue-router'; |
|||
import { ref } from 'vue'; |
|||
import { useI18n } from 'vue-i18n'; |
|||
import { Environment, axios } from '@/platform'; |
|||
import { Environment } from '@/platform'; |
|||
|
|||
const route = useRoute(); |
|||
const { t } = useI18n(); |
|||
|
|||
const corporationTreeGridRef = ref(); |
|||
|
|||
const corporationConfigure = { |
|||
actions: [ |
|||
{ |
|||
name: 'refresh', |
|||
label: t('refresh'), |
|||
click: () => {}, |
|||
}, |
|||
|
|||
{ |
|||
name: 'addRoot', |
|||
label: t('system.corporation.action.addTop'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'addChild', |
|||
label: t('system.corporation.action.addChild'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'edit', |
|||
label: t('edit'), |
|||
click: () => {}, |
|||
}, |
|||
{ |
|||
name: 'delete', |
|||
label: t('delete'), |
|||
click: () => {}, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
onMounted(() => { |
|||
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => { |
|||
corporationTreeGridRef.value.setNodes(response.data.content); |
|||
}); |
|||
}); |
|||
const columns = [ |
|||
{ |
|||
name: 'name', |
|||
required: true, |
|||
label: 'Dessert (100g serving)', |
|||
align: 'left', |
|||
field: 'name', |
|||
sortable: true, |
|||
}, |
|||
{ 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) }, |
|||
]; |
|||
</script> |
|||
|
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<div class="flex flex-nowrap py-2"> |
|||
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div> |
|||
<q-space /> |
|||
<div ref="actionContainerRef" class="flex flex-nowrap"> |
|||
<!-- baseActions --> |
|||
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index"> |
|||
<q-separator |
|||
v-if="action.separator" |
|||
vertical |
|||
class="class-action-item" |
|||
:style="{ |
|||
'margin-left': '5px', |
|||
'margin-right': '5px', |
|||
}" |
|||
/> |
|||
<q-btn |
|||
v-else |
|||
v-bind="action" |
|||
:id="action.name" |
|||
:disable="action.enableIf ? !action.enableIf() : false" |
|||
no-wrap |
|||
class="class-action-item" |
|||
:style="{ |
|||
'margin-left': '5px', |
|||
'margin-right': '5px', |
|||
}" |
|||
@click="action.click" |
|||
/> |
|||
</template> |
|||
|
|||
<!-- moreActions --> |
|||
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px"> |
|||
<q-list> |
|||
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index"> |
|||
<q-separator v-if="action.separator" /> |
|||
<q-item v-else v-close-popup clickable @click="action.click"> |
|||
<q-item-section avatar style="min-width: 28px; padding-right: 0px"> |
|||
<q-icon :name="action.icon" size="20px" /> |
|||
</q-item-section> |
|||
<q-item-section> |
|||
<q-item-label :v-bind="action">{{ action.label }}</q-item-label> |
|||
</q-item-section> |
|||
</q-item> |
|||
</template> |
|||
</q-list> |
|||
</q-btn-dropdown> |
|||
</div> |
|||
<q-resize-observer @resize="onResize" /> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref } from 'vue'; |
|||
import { Tools } from '@/platform/utils'; |
|||
|
|||
const props = defineProps({ |
|||
title: { type: String, default: '' }, |
|||
actions: { |
|||
type: Array, |
|||
default: () => { |
|||
return []; |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
const titleContainerRef = ref(); |
|||
const actionContainerRef = ref(); |
|||
|
|||
const actions = props.actions; |
|||
const baseActions = ref(actions); |
|||
const moreActions = ref([]); |
|||
const isActionWidthInitializedRef = ref(false); |
|||
const moreActionWidth = 100; |
|||
|
|||
const onResize = (size) => { |
|||
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) { |
|||
return; |
|||
} |
|||
|
|||
if (!isActionWidthInitializedRef.value) { |
|||
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item'); |
|||
for (let i = 0; i < actions.length; i++) { |
|||
actions[i].width = nodes[i].clientWidth + 10; |
|||
} |
|||
isActionWidthInitializedRef.value = true; |
|||
} |
|||
|
|||
const _baseActions = []; |
|||
const _moreActions = []; |
|||
const length = actions.length; |
|||
let availableWidth = size.width - titleContainerRef.value.clientWidth; |
|||
let width = 0; |
|||
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) { |
|||
index--; |
|||
width -= actions[index].width; |
|||
_baseActions.pop(); |
|||
} |
|||
break; |
|||
} else { |
|||
_baseActions.push(actions[index]); |
|||
width += actions[index].width; |
|||
} |
|||
} |
|||
|
|||
for (; index < length; index++) { |
|||
_moreActions.push(actions[index]); |
|||
} |
|||
|
|||
baseActions.value = _baseActions; |
|||
moreActions.value = _moreActions; |
|||
}; |
|||
</script> |
@ -0,0 +1,6 @@ |
|||
dependencies { |
|||
api( |
|||
project(":io.sc.platform.core"), |
|||
project(":io.sc.platform.orm.api"), |
|||
) |
|||
} |
@ -0,0 +1,7 @@ |
|||
package io.sc.platform.job.core.enums; |
|||
|
|||
public enum BlockStrategy { |
|||
SERIAL_EXECUTION, //单机串行
|
|||
DISCARD_LATER, //丢弃后续调度
|
|||
COVER_EARLY; //覆盖先前调度
|
|||
} |
@ -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; //分片广播
|
|||
} |
@ -0,0 +1,6 @@ |
|||
package io.sc.platform.job.core.enums; |
|||
|
|||
public enum ExpirationPolicy { |
|||
DO_NOTHING, //忽略
|
|||
FIRE_ONCE_NOW; //立即执行一次
|
|||
} |
@ -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
|
|||
} |
@ -0,0 +1,7 @@ |
|||
package io.sc.platform.job.core.enums; |
|||
|
|||
public enum TaskScheduleType { |
|||
NONE, //无
|
|||
CRON, //Cron
|
|||
FIX_RATE; //固定周期
|
|||
} |
@ -0,0 +1,6 @@ |
|||
package io.sc.platform.job.core.enums; |
|||
|
|||
public enum TriggerStatus { |
|||
STOPED, //已停止
|
|||
RUNNING; //运行中
|
|||
} |
@ -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<Runnable>(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<Long> 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<String> callback(List<HandleCallbackParam> callbackParamList) { |
|||
|
|||
callbackThreadPool.execute(new Runnable() { |
|||
@Override |
|||
public void run() { |
|||
for (HandleCallbackParam handleCallbackParam: callbackParamList) { |
|||
ReturnT<String> callbackResult = callback(handleCallbackParam); |
|||
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}", |
|||
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return ReturnT.SUCCESS; |
|||
} |
|||
|
|||
private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) { |
|||
// valid log item
|
|||
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId()); |
|||
if (log == null) { |
|||
return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found."); |
|||
} |
|||
if (log.getHandleCode() > 0) { |
|||
return new ReturnT<String>(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("<br>"); |
|||
} |
|||
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; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
@ -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<Long> 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 = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>"; |
|||
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); |
|||
} |
|||
} |
|||
|
|||
} |
@ -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<String, Object> 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<Long> 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); |
|||
} |
|||
} |
|||
|
|||
} |
@ -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<Runnable>(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<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0); |
|||
if (groupList!=null && !groupList.isEmpty()) { |
|||
|
|||
// remove dead address (admin/executor)
|
|||
List<Integer> 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<String, List<String>> appAddressMap = new HashMap<String, List<String>>(); |
|||
List<XxlJobRegistry> 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<String> registryList = appAddressMap.get(appname); |
|||
if (registryList == null) { |
|||
registryList = new ArrayList<String>(); |
|||
} |
|||
|
|||
if (!registryList.contains(item.getRegistryValue())) { |
|||
registryList.add(item.getRegistryValue()); |
|||
} |
|||
appAddressMap.put(appname, registryList); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// fresh group address
|
|||
for (XxlJobGroup group: groupList) { |
|||
List<String> 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<String> registry(RegistryParam registryParam) { |
|||
|
|||
// valid
|
|||
if (!StringUtils.hasText(registryParam.getRegistryGroup()) |
|||
|| !StringUtils.hasText(registryParam.getRegistryKey()) |
|||
|| !StringUtils.hasText(registryParam.getRegistryValue())) { |
|||
return new ReturnT<String>(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<String> registryRemove(RegistryParam registryParam) { |
|||
|
|||
// valid
|
|||
if (!StringUtils.hasText(registryParam.getRegistryGroup()) |
|||
|| !StringUtils.hasText(registryParam.getRegistryKey()) |
|||
|| !StringUtils.hasText(registryParam.getRegistryValue())) { |
|||
return new ReturnT<String>(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
|
|||
} |
|||
|
|||
|
|||
} |
@ -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<Integer, List<Integer>> 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<XxlJobInfo> 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<Integer> ringItemData = new ArrayList<>(); |
|||
int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
|
|||
for (int i = 0; i < 2; i++) { |
|||
List<Integer> 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<Integer> ringItemData = ringData.get(ringSecond); |
|||
if (ringItemData == null) { |
|||
ringItemData = new ArrayList<Integer>(); |
|||
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<Integer> 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; |
|||
} |
|||
|
|||
} |
@ -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<Runnable>(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<Runnable>(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<Integer, AtomicInteger> 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); |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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<String> 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<String> getAddresses() { |
|||
return addresses; |
|||
} |
|||
|
|||
public void setAddresses(Set<String> addresses) { |
|||
this.addresses = addresses; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -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<ExecutorRegistryVo> { |
|||
//主键
|
|||
@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; |
|||
} |
|||
} |
@ -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<TaskVo> { |
|||
//主键
|
|||
@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; |
|||
} |
|||
} |
@ -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<TaskLogVo> { |
|||
//主键
|
|||
@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; |
|||
} |
|||
} |
@ -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<TaskLogReportVo> { |
|||
//主键
|
|||
@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; |
|||
} |
|||
} |
@ -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<ExecutorRegistryEntity,String> { |
|||
} |
@ -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<JobGroupEntity,String> { |
|||
public List<JobGroupEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType); |
|||
public interface ExecutorRepository extends DaoRepository<ExecutorEntity,String> { |
|||
public List<ExecutorEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType); |
|||
} |
@ -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<TaskLogReportEntity,String> { |
|||
} |
@ -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<TaskLogEntity,String> { |
|||
} |
@ -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<TaskEntity,String> { |
|||
} |
@ -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<TaskEntity, String, TaskRepository> { |
|||
public void start(int id); |
|||
public void stop(int id); |
|||
} |
@ -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<TaskEntity, String, TaskRepository> 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<String>(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<String>(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<String>(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) { |
|||
|
|||
} |
|||
} |
Loading…
Reference in new issue