feat:执行计划修改重试策略

1.执行计划atu-execute-plan
2.执行引擎atu-script-engine
3.服务atu-execute-plan增加表atu_plan_task_record
4.服务atu-execute-plan修改表:atu_plan_info,增加字段retry_strategy重试策略
5.ddl语句在atu-execute-plan的resource/mysql/ddl.sql文件里
master
李杰应 2024-10-17 13:28:21 +08:00
parent cab4c50752
commit 7349ed567d
34 changed files with 1329 additions and 12 deletions

View File

@ -446,7 +446,7 @@ public class DefaultExecThread implements AtuExecThread{
RabbitTemplate rabbitTemplate = SpringUtil.getBean(RabbitTemplate.class);
rabbitTemplate.convertAndSend(AtuExecConstant.TASK_EXEC_RESULT, JsonUtils.toJson(result));
if (!AtuExecConstant.TASK_START.equalsIgnoreCase(type)) {
if (!AtuExecConstant.TASK_START.equalsIgnoreCase(type) && !AtuExecConstant.TASK_RETRY.equals(type)) {
log.debug("清理正在执行中任务数据");
AtuTaskExecHeartbeatSchedule.execTaskMap.remove(result.getTaskId());
}
@ -741,6 +741,9 @@ public class DefaultExecThread implements AtuExecThread{
if(task.getFailRetryNum()>0){
retry = task.getFailRetryNum()+1;
}
if (AtuExecConstant.TASK_RETRY_STRATEGY_PACKAGE.equals(task.getRetryStrategy())) { // 重试策略如果是失败任务打包重试那么重试次数应该为0由计划执行完一轮后统一下发
retry = 1;
}
// 创建脚本执行器
this.scriptExecutor = SpringUtils.getBean(ScriptResolutionService.class).getScriptExecutor(task.getTaskId());
if (null == scriptExecutor){
@ -836,6 +839,8 @@ public class DefaultExecThread implements AtuExecThread{
executeResult.setResultMsg(ae.getMessage());
}
executeResult.setResultStatus(2);
// 更新结果到计划服务,新增一条执行记录,用于记录任务重试
retryExecuteCheck(j + 1 < retry, result, AtuExecConstant.TASK_ASSERT_FAIL);
}catch (Exception e) {
//执行失败
log.error("第["+j+"]次执行任务执行失败:",e);
@ -847,6 +852,8 @@ public class DefaultExecThread implements AtuExecThread{
executeResult.setResultMsg(msg);
}
executeResult.setResultStatus(1);
// 更新结果到计划服务,新增一条执行记录,用于记录任务重试
retryExecuteCheck(j + 1 < retry, result, AtuExecConstant.TASK_ASSERT_FAIL);
}
}
try {
@ -935,6 +942,27 @@ public class DefaultExecThread implements AtuExecThread{
}
}
/**
*
* @param result
*/
private void retryExecuteCheck(boolean forFlag, TaskExecResult result, String resultStatus) {
if (!forFlag) {
return;
}
try {
result.setNeedRetry(true);
if ((task.getRetryStrategy() != null && AtuExecConstant.TASK_RETRY_STRATEGY_SINGLE.equals(task.getRetryStrategy())) || (task.getFailRetryNum() > 0 && StringUtils.isBlank(task.getRetryStrategy()))) { // 单条重试兼容以前没有但是重试次数不为0
log.debug("发送信息到平台保存记录,准备重试...");
updateExecResult(result, resultStatus, "");
}
} catch (Exception e) {
log.error("新增任务[{}]执行记录失败", task.getTaskId(), e);
} finally {
result.setNeedRetry(false);
}
}
private Script getScriptInfo(String scriptPath){
AtuServerConfig config = SpringUtils.getBean(AtuServerConfig.class);
String url = config.getServerUrl() + config.getFileDownloadPath() + scriptPath;

View File

@ -16,6 +16,11 @@ public class AtuExecConstant {
public static final String TASK_ASSERT_FAIL = "4";
public static final String TASK_CANCEL = "5";
public static final String TASK_RETRY = "10";
public static final String TASK_RETRY_STRATEGY_PACKAGE = "1";
public static final String TASK_RETRY_STRATEGY_SINGLE = "2";
/**
*
*/

View File

@ -35,6 +35,11 @@ public class AutoTask {
private int failRetryNum;
/**
*
*/
private String retryStrategy;
private String appId;
private String projectId;
@ -214,4 +219,12 @@ public class AutoTask {
public void setEnvId(String envId) {
this.envId = envId;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -27,6 +27,8 @@ public class TaskExecResult {
//任务状态 1-开始执行2-执行成功3-执行失败4-断言失败5-取消6-超时
private String status;
private boolean needRetry;
private String message;
private String currentTime;

View File

@ -1160,6 +1160,14 @@ public class AtuPlanInfoApiServiceImpl extends AbstractExcelService<AtuPlanInfo>
entity.setUpdatedBy(NKSecurityContext.getUserId());
entity.setUpdatedTime(new Date());
this.atuPlanInfoService.updatePlanRetryCount(entity);
if (entity.getFailRetry()) {
if (entity.getRetryStrategy() == null) {
entity.setRetryStrategy(PlanConstant.TASK_RETRY_STRATEGY_PACKAGE);
}
} else {
entity.setFailRetryCount(0);
entity.setRetryStrategy(null);
}
this.atuPlanInfoService.updateByPrimaryKey(entity);
entity.setPrincipalId(planInfo.getPrincipalId());
} else {
@ -1172,6 +1180,9 @@ public class AtuPlanInfoApiServiceImpl extends AbstractExcelService<AtuPlanInfo>
entity.setCreatedTime(new Date());
entity.setUpdatedBy(NKSecurityContext.getUserId());
entity.setUpdatedTime(new Date());
if (dto.getFailRetry() != null && dto.getFailRetry() && dto.getRetryStrategy() == null) { // 失败重试并且重试策略为空的情况下,默认使用策略:失败任务打包重试
entity.setRetryStrategy(PlanConstant.TASK_RETRY_STRATEGY_PACKAGE);
}
this.atuPlanInfoService.insert(entity);
}
logger.info("-------------------->保存计划基础信息");
@ -2635,6 +2646,9 @@ public class AtuPlanInfoApiServiceImpl extends AbstractExcelService<AtuPlanInfo>
if (CollUtil.isEmpty(inputDataList)) {
throw new PlatformRuntimeException(ExecPlanError.SCRIPT_INPUT_DATA_IS_NULL);
}
if (planInfo.getFailRetry() && PlanConstant.TASK_RETRY_STRATEGY_PACKAGE.equals(planInfo.getRetryStrategy())) {
redisTemplate.opsForHash().put(RedisConstant.PLAN_BATCH_RETRY_COUNT, planBatch.getId(), planInfo.getFailRetryCount());
}
// 异步生成任务
executor.execute(() ->{
boolean hasOfflineDevice = StrUtil.isNotBlank(atuPlanRunDto.getBatchId());

View File

@ -16,8 +16,10 @@ import net.northking.cctp.executePlan.constants.RedisConstant;
import net.northking.cctp.executePlan.db.entity.AtuPlanInfo;
import net.northking.cctp.executePlan.db.entity.AtuPlanSceneCaseTask;
import net.northking.cctp.executePlan.db.entity.AtuPlanTask;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.executePlan.db.service.AtuPlanInfoService;
import net.northking.cctp.executePlan.db.service.AtuPlanSceneCaseTaskService;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskRecordService;
import net.northking.cctp.executePlan.dto.planBatch.AppPerInfo;
import net.northking.cctp.executePlan.dto.planBatch.DevicePerInfo;
import net.northking.cctp.executePlan.dto.planBatch.MobileTaskPerformanceDto;
@ -74,6 +76,9 @@ public class AtuPlanSceneCaseTaskApiServiceImpl implements AtuPlanSceneCaseTaskA
@Autowired
private SimpleStorageService simpleStorageService;
@Autowired
private AtuPlanTaskRecordService planTaskRecordService;
/**
*
* @param taskExecResult
@ -228,7 +233,8 @@ public class AtuPlanSceneCaseTaskApiServiceImpl implements AtuPlanSceneCaseTaskA
}
logger.debug("更新场景任务为结束");
planTaskApiService.updateByPrimaryKey(planTask);
// 添加任务记录到表atu_plan_task_record
addTaskRecord(taskExecResult, planTask);
// 更新批次统计数据
planBatchApiService.updateCacheBatchSumData(planTask);
// 删除节点更新时的场景任务文件
@ -246,6 +252,32 @@ public class AtuPlanSceneCaseTaskApiServiceImpl implements AtuPlanSceneCaseTaskA
}
}
private void addTaskRecord(AtuTaskExecResultDto taskExecResult, AtuPlanTask planTask) {
try {
planTask.setEndTime(taskExecResult.getCurrentTime());
AtuPlanTaskRecord record = new AtuPlanTaskRecord();
record.setTaskId(planTask.getId());
// 根据taskId查询执行序号
long count = planTaskRecordService.count(record);
if (count > 0) {
record.setExecuteType(PlanConstant.TASK_EXECUTE_TYPE_AUTO_RETRY);
}
record.setExecIdx(Math.toIntExact(count) + 1);
// 插入执行任务记录
record.setId(UUIDUtil.create32UUID());
record.setStartTime(planTask.getStartTime()); // 任务开始时间
record.setEndTime(planTask.getEndTime()); // 任务结束时间
record.setBatchId(planTask.getBatchId()); // 批次
record.setErrorMsg(taskExecResult.getMessage()); // 任务错误信息
record.setExecResultFile(taskExecResult.getFilePath()); // 任务执行记录结果文件地址
record.setVideoUrl(taskExecResult.getVideoPath()); // 任务执行录屏文件地址
planTaskRecordService.insert(record);
} catch (Exception e) {
logger.error("新增任务记录失败", e);
}
}
/**
*
* @param planSceneCaseTask
@ -297,6 +329,8 @@ public class AtuPlanSceneCaseTaskApiServiceImpl implements AtuPlanSceneCaseTaskA
atuTaskExecDto.setScreenRecordSet(planInfo.getScreenRecordSet());
atuTaskExecDto.setScreenshotSet(planInfo.getScreenshotSet());
atuTaskExecDto.setFailRetryNum(planInfo.getFailRetryCount());
// 重试策略
atuTaskExecDto.setRetryStrategy(planInfo.getRetryStrategy());
atuTaskExecDto.setAppId(planTaskApiService.queryAppId(planInfo.getId(), nodeInfo.getPlatformType(),
nodeInfo.getAppPackage(), nodeInfo.getNodeType()));

View File

@ -33,10 +33,7 @@ import net.northking.cctp.executePlan.constants.PlanConstant;
import net.northking.cctp.executePlan.constants.RabbitConstant;
import net.northking.cctp.executePlan.constants.RedisConstant;
import net.northking.cctp.executePlan.db.entity.*;
import net.northking.cctp.executePlan.db.service.AtuPlanAppLinkService;
import net.northking.cctp.executePlan.db.service.AtuPlanBatchDeviceLinkService;
import net.northking.cctp.executePlan.db.service.AtuPlanSceneCaseTaskService;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskService;
import net.northking.cctp.executePlan.db.service.*;
import net.northking.cctp.executePlan.dto.planBatch.AtuBatchCaseInfoDto;
import net.northking.cctp.executePlan.dto.planBatch.AtuExceptionCase;
import net.northking.cctp.executePlan.dto.planBatch.BatchRetryDto;
@ -140,6 +137,8 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private AtuPlanTaskRecordService taskRecordService;
@Autowired
private EnvNameUtils envNameUtils;
@ -327,9 +326,29 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
}
}
}
queryTaskExecTake(pagination.getRecords());
return pagination;
}
private void queryTaskExecTake(List<AtuPlanTaskPageDto> records) {
try {
if (!records.isEmpty()) {
List<String> ids = records.stream().map(AtuPlanTaskPageDto::getId).collect(Collectors.toList());
List<PlanTaskRecordDto> taskRecords = taskRecordService.queryTotalTake(ids);
if (!taskRecords.isEmpty()) {
Map<String, PlanTaskRecordDto> collectMap = taskRecords.stream().collect(Collectors.toMap(PlanTaskRecordDto::getTaskId, Function.identity()));
for (AtuPlanTaskPageDto record : records) {
if (collectMap.containsKey(record.getId())) {
record.setTotalExecTake(collectMap.get(record.getId()).getTotalTake());
}
}
}
}
} catch (Exception e) {
logger.error("查询任务的总耗时失败", e);
}
}
@Override
public List<AtuPlanTask> query(AtuPlanTask atuPlanTask) {
return atuPlanTaskService.query(atuPlanTask);
@ -448,6 +467,8 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
String type = planTask.getCaseType();
atuTaskExecDto.setCaseType(type);
atuTaskExecDto.setFailRetryNum(batchCaseInfo.getFailRetryCount());
// 重试策略
atuTaskExecDto.setRetryStrategy(batchCaseInfo.getRetryStrategy());
boolean deviceOffline = false;
if (ObjectUtil.equal(PlanConstant.SCRIPT_TYPE_SCENE, type)) {
// 场景用例
@ -1336,6 +1357,8 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
caseInfoDto.setFailRetryCount(0);
if (planInfo.getFailRetry()) {
caseInfoDto.setFailRetryCount(planInfo.getFailRetryCount());
// 重试策略
caseInfoDto.setRetryStrategy(planInfo.getRetryStrategy());
}
// 判断是否场景用例

View File

@ -126,7 +126,30 @@ public class PlanConstant {
*
*/
public static final String TASK_TIMEOUT_STATUS = "6";
/**
*
*/
public static final String TASK_RETRY_STATUS = "10";
/**
*
*/
public static final String TASK_EXECUTE_TYPE_NORMAL = "0";
/**
*
*/
public static final String TASK_EXECUTE_TYPE_AUTO_RETRY = "1";
/**
*
*/
public static final String TASK_EXECUTE_TYPE_MANUAL_RETRY = "2";
/**
*
*/
public static final String TASK_RETRY_STRATEGY_PACKAGE = "1";
/**
*
*/
public static final String TASK_RETRY_STRATEGY_SINGLE = "2";
/**
* key
*/

View File

@ -27,6 +27,8 @@ public class RedisConstant {
public static final TimeUnit PLAN_BATCH_OFFLINE_DEVICE_TIME_UNIT = TimeUnit.HOURS;
public static final String PLAN_BATCH_RETRY_COUNT = "plan:batch:retry-count:";
/**
*
*/

View File

@ -9,7 +9,9 @@ import net.northking.cctp.executePlan.constants.PlanConstant;
import net.northking.cctp.executePlan.constants.RabbitConstant;
import net.northking.cctp.executePlan.constants.RedisConstant;
import net.northking.cctp.executePlan.db.entity.AtuPlanTask;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.executePlan.db.service.AtuPlanInfoService;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskRecordService;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskService;
import net.northking.cctp.executePlan.dto.planTask.AtuTaskExecResultDto;
import org.slf4j.Logger;
@ -57,6 +59,9 @@ public class TaskExecResultConsumer {
@Autowired
private AtuPlanSceneCaseTaskApiService sceneCaseTaskApiService;
@Autowired
private AtuPlanTaskRecordService taskRecordService;
@PostConstruct
public void init(){
// 初始化队列并绑定到交换机
@ -120,12 +125,25 @@ public class TaskExecResultConsumer {
atuPlanInfoService.updatePlanByLastBatchId(planTask.getBatchId(), PlanConstant.PLAN_EXECUTING_STATUS);
}
}else if(taskExecResult.isNeedRetry()) { // 任务需要失败后需要重试
// 添加任务执行记录
addTaskRecord(taskExecResult, planTask);
// 任务重试,结束时间作为重试的开始时间
AtuPlanTask updateTaskTime = new AtuPlanTask();
updateTaskTime.setId(planTask.getId());
updateTaskTime.setStartTime(taskExecResult.getCurrentTime());
planTaskService.updateByPrimaryKey(updateTaskTime);
// 结束
return;
}else{
planTask.setStatus(taskExecResult.getStatus());
planTask.setEndTime(taskExecResult.getCurrentTime());
planTask.setErrorMsg(taskExecResult.getMessage());
planTask.setVideoUrl(taskExecResult.getVideoPath());
planTask.setExecResultFile(taskExecResult.getFilePath());
// 任务完成后查询数据后将数据插入到表atu_plan_task_record
addTaskRecord(taskExecResult, planTask);
}
if (PlanConstant.SCRIPT_TYPE_ANDROID.equals(planTask.getCaseType())
@ -153,5 +171,32 @@ public class TaskExecResultConsumer {
logger.error("任务结果更新失败", e);
}
}
private void addTaskRecord(AtuTaskExecResultDto taskExecResult, AtuPlanTask planTask) {
try {
planTask.setEndTime(taskExecResult.getCurrentTime());
AtuPlanTaskRecord record = new AtuPlanTaskRecord();
record.setTaskId(planTask.getId());
// 根据taskId查询执行序号
long count = taskRecordService.count(record);
if (count > 0) {
record.setExecuteType(PlanConstant.TASK_EXECUTE_TYPE_AUTO_RETRY);
}
record.setExecIdx(Math.toIntExact(count) + 1);
// 插入执行任务记录
record.setId(UUIDUtil.create32UUID());
record.setStartTime(planTask.getStartTime()); // 任务开始时间
record.setEndTime(planTask.getEndTime()); // 任务结束时间
record.setStatus(taskExecResult.getStatus()); // 执行结果
record.setBatchId(planTask.getBatchId()); // 批次
record.setErrorMsg(taskExecResult.getMessage()); // 任务错误信息
record.setExecResultFile(taskExecResult.getFilePath()); // 任务执行记录结果文件地址
record.setVideoUrl(taskExecResult.getVideoPath()); // 任务执行录屏文件地址
taskRecordService.insert(record);
} catch (Exception e) {
logger.error("新增任务记录失败", e);
}
}
}

View File

@ -65,6 +65,12 @@ public interface AtuPlanTaskDao extends AtuPlanTaskMapper
*/
Long queryBatchFirstTaskStartTime(String batchId);
/**
* IDID
* @param batchId ID
* @return ID
*/
List<String> queryAllFailIdList(String batchId);
List<AtuPlanTaskPageDto> selectCaseListByBatchId(String batchId);

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) Corporation 2024 . All rights reserved.
*
*/
package net.northking.cctp.executePlan.db.dao;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.executePlan.db.mapper.AtuPlanTaskRecordMapper;
import net.northking.cctp.executePlan.dto.planTask.PlanTaskRecordDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Mybatis
*
* <p> <br>
* createdate: 2024-10-16 17:02:48 <br>
* @author: maven-cctp-plugin <br>
* @since: 1.0 <br>
*/
@Repository
public interface AtuPlanTaskRecordDao extends AtuPlanTaskRecordMapper
{
List<PlanTaskRecordDto> queryTotalTake(@Param("taskIds") List<String> taskIds);
}

View File

@ -175,6 +175,11 @@ public class AtuPlanInfo extends TenantPartition implements Entity
*/
@ApiModelProperty("失败重试次数")
private Integer failRetryCount;
/**
* <br>
*/
@ApiModelProperty("重试策略")
private String retryStrategy;
/**
* ;0-1-<br>
*/
@ -1009,4 +1014,11 @@ public class AtuPlanInfo extends TenantPartition implements Entity
{
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -0,0 +1,303 @@
/*
* Copyright (c) Corporation 2024 . All rights reserved.
*
*/
package net.northking.cctp.executePlan.db.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.Size;
import net.northking.cctp.common.db.POJO;
import net.northking.cctp.common.db.Partition;
import net.northking.cctp.common.db.entity.Entity;
import net.northking.cctp.common.validation.ValAddGroup;
import net.northking.cctp.common.validation.ValUpdateGroup;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* <p> <br>
* createdate: 2024-10-16 17:02:48 <br>
* @author: maven-cctp-plugin <br>
* @since: 1.0 <br>
*/
@ApiModel(description = "任务执行记录表")
public class AtuPlanTaskRecord extends Partition implements POJO
{
public static final String KEY_id = "id";
public static final String KEY_taskId = "taskId";
public static final String KEY_batchId = "batchId";
public static final String KEY_execIdx = "execIdx";
public static final String KEY_startTime = "startTime";
public static final String KEY_endTime = "endTime";
public static final String KEY_executeType = "executeType";
public static final String KEY_status = "status";
public static final String KEY_errorMsg = "errorMsg";
public static final String KEY_videoUrl = "videoUrl";
public static final String KEY_execResultFile = "execResultFile";
/**
* id<br>
*/
@ApiModelProperty("记录id")
@Size(max = 32, message="记录id-id: 数据长度不能 > 32" )
private String id;
/**
* id<br>
*/
@ApiModelProperty("任务id")
@Size(max = 32, message="任务id-taskId: 数据长度不能 > 32" )
private String taskId;
/**
* id<br>
*/
@ApiModelProperty("批次id")
@Size(max = 32, message="批次id-batchId: 数据长度不能 > 32" )
private String batchId;
/**
* <br>
*/
@ApiModelProperty("执行序号")
private Integer execIdx;
/**
* <br>
*/
@ApiModelProperty("开始时间")
private Long startTime;
/**
* <br>
*/
@ApiModelProperty("结束时间")
private Long endTime;
/**
* 0-|1-|2-<br>
*/
@ApiModelProperty("执行类型0-正常执行|1-自动重试|2-手动重试")
@Size(max = 10, message="执行类型0-正常执行|1-自动重试|2-手动重试-executeType: 数据长度不能 > 10" )
private String executeType;
/**
* <br>
*/
@ApiModelProperty("状态")
@Size(max = 10, message="状态-status: 数据长度不能 > 10" )
private String status;
/**
* <br>
*/
@ApiModelProperty("错误信息")
@Size(max = 65535, message="错误信息-errorMsg: 数据长度不能 > 65535" )
private String errorMsg;
/**
* <br>
*/
@ApiModelProperty("视频地址")
@Size(max = 255, message="视频地址-videoUrl: 数据长度不能 > 255" )
private String videoUrl;
/**
* <br>
*/
@ApiModelProperty("执行结果文件")
@Size(max = 255, message="执行结果文件-execResultFile: 数据长度不能 > 255" )
private String execResultFile;
/**
* id<br>
*/
public String getId()
{
return id;
}
/**
* id<br>
*
* @param id id
*/
public void setId(String id)
{
this.id = id;
}
/**
* id<br>
*/
public String getTaskId()
{
return taskId;
}
/**
* id<br>
*
* @param taskId id
*/
public void setTaskId(String taskId)
{
this.taskId = taskId;
}
/**
* id<br>
*/
public String getBatchId()
{
return batchId;
}
/**
* id<br>
*
* @param batchId id
*/
public void setBatchId(String batchId)
{
this.batchId = batchId;
}
/**
* <br>
*/
public Integer getExecIdx()
{
return execIdx;
}
/**
* <br>
*
* @param execIdx
*/
public void setExecIdx(Integer execIdx)
{
this.execIdx = execIdx;
}
/**
* <br>
*/
public Long getStartTime()
{
return startTime;
}
/**
* <br>
*
* @param startTime
*/
public void setStartTime(Long startTime)
{
this.startTime = startTime;
}
/**
* <br>
*/
public Long getEndTime()
{
return endTime;
}
/**
* <br>
*
* @param endTime
*/
public void setEndTime(Long endTime)
{
this.endTime = endTime;
}
/**
* 0-|1-|2-<br>
*/
public String getExecuteType()
{
return executeType;
}
/**
* 0-|1-|2-<br>
*
* @param executeType 0-|1-|2-
*/
public void setExecuteType(String executeType)
{
this.executeType = executeType;
}
/**
* <br>
*/
public String getStatus()
{
return status;
}
/**
* <br>
*
* @param status
*/
public void setStatus(String status)
{
this.status = status;
}
/**
* <br>
*/
public String getErrorMsg()
{
return errorMsg;
}
/**
* <br>
*
* @param errorMsg
*/
public void setErrorMsg(String errorMsg)
{
this.errorMsg = errorMsg;
}
/**
* <br>
*/
public String getVideoUrl()
{
return videoUrl;
}
/**
* <br>
*
* @param videoUrl
*/
public void setVideoUrl(String videoUrl)
{
this.videoUrl = videoUrl;
}
/**
* <br>
*/
public String getExecResultFile()
{
return execResultFile;
}
/**
* <br>
*
* @param execResultFile
*/
public void setExecResultFile(String execResultFile)
{
this.execResultFile = execResultFile;
}
public AtuPlanTaskRecord()
{
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) Corporation 2024 . All rights reserved.
*
*/
package net.northking.cctp.executePlan.db.impl;
import net.northking.cctp.executePlan.db.dao.AtuPlanTaskRecordDao;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskRecordService;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.common.db.BasicDao;
import net.northking.cctp.common.db.PaginationService;
import net.northking.cctp.executePlan.dto.planTask.PlanTaskRecordDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*
*
* <p> <br>
* createdate: 2024-10-16 17:02:48 <br>
*
* @author: maven-cctp-plugin <br>
* @since: 1.0 <br>
*/
@Service
@ConditionalOnMissingBean(name = "AtuPlanTaskRecordServiceImpl")
public class AtuPlanTaskRecordServiceImpl extends PaginationService<AtuPlanTaskRecord> implements AtuPlanTaskRecordService {
private static final Logger logger = LoggerFactory.getLogger(AtuPlanTaskRecordServiceImpl.class);
private final AtuPlanTaskRecordDao atuPlanTaskRecordDao;
public AtuPlanTaskRecordServiceImpl(AtuPlanTaskRecordDao atuPlanTaskRecordDao) {
this.atuPlanTaskRecordDao = atuPlanTaskRecordDao;
}
public BasicDao<AtuPlanTaskRecord> getDao() {
return atuPlanTaskRecordDao;
}
public AtuPlanTaskRecord createEntity() {
return new AtuPlanTaskRecord();
}
@Override
protected void beforeInsert(AtuPlanTaskRecord record) {
}
@Override
protected void beforeUpdate(AtuPlanTaskRecord record) {
}
// ---- The End by Generator ----//
@Override
public List<PlanTaskRecordDto> queryTotalTake(List<String> ids) {
return atuPlanTaskRecordDao.queryTotalTake(ids);
}
}

View File

@ -87,6 +87,10 @@ private static final Logger logger = LoggerFactory.getLogger(AtuPlanTaskServiceI
return atuPlanTaskDao.queryBatchFirstTaskStartTime(batchId);
}
@Override
public List<String> queryAllFailIdList(String batchId) {
return atuPlanTaskDao.queryAllFailIdList(batchId);
}
@Override

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) Corporation 2024 . All rights reserved.
*
*/
package net.northking.cctp.executePlan.db.mapper;
import net.northking.cctp.executePlan.db.dao.AtuPlanTaskRecordDao;
import net.northking.cctp.executePlan.db.service.AtuPlanTaskRecordService;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.common.db.BasicDao;
import net.northking.cctp.common.db.PaginationService;
import net.northking.cctp.executePlan.dto.planTask.PlanTaskRecordDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import java.util.List;
/**
*
*
* <p> <br>
* createdate: 2024-10-16 17:02:48 <br>
*
* @author: maven-cctp-plugin <br>
* @since: 1.0 <br>
*/
@Service
@ConditionalOnMissingBean(name = "AtuPlanTaskRecordServiceImpl")
public class AtuPlanTaskRecordServiceImpl extends PaginationService<AtuPlanTaskRecord> implements AtuPlanTaskRecordService {
private static final Logger logger = LoggerFactory.getLogger(AtuPlanTaskRecordServiceImpl.class);
private final AtuPlanTaskRecordDao atuPlanTaskRecordDao;
public AtuPlanTaskRecordServiceImpl(AtuPlanTaskRecordDao atuPlanTaskRecordDao) {
this.atuPlanTaskRecordDao = atuPlanTaskRecordDao;
}
public BasicDao<AtuPlanTaskRecord> getDao() {
return atuPlanTaskRecordDao;
}
public AtuPlanTaskRecord createEntity() {
return new AtuPlanTaskRecord();
}
@Override
protected void beforeInsert(AtuPlanTaskRecord record) {
}
@Override
protected void beforeUpdate(AtuPlanTaskRecord record) {
}
// ---- The End by Generator ----//
@Override
public List<PlanTaskRecordDto> queryTotalTake(List<String> ids) {
return atuPlanTaskRecordDao.queryTotalTake(ids);
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) Corporation 2024 . All rights reserved.
*
*/
package net.northking.cctp.executePlan.db.service;
import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord;
import net.northking.cctp.executePlan.dto.planTask.PlanTaskRecordDto;
import java.util.List;
/**
*
*
* <p> <br>
* createdate: 2024-10-16 17:02:48 <br>
* @author: maven-cctp-plugin <br>
* @since: 1.0 <br>
*/
public interface AtuPlanTaskRecordService extends BasicService<AtuPlanTaskRecord>
{
// ---- The End by Generator ----//
List<PlanTaskRecordDto> queryTotalTake(List<String> ids);
}

View File

@ -62,6 +62,12 @@ public interface AtuPlanTaskService extends BasicService<AtuPlanTask>
*/
Long queryBatchFirstTaskStartTime(String batchId);
/**
* IDID
* @param batchId ID
* @return ID
*/
List<String> queryAllFailIdList(String batchId);
List<AtuPlanTaskPageDto> queryCaseListByBatchId(String batchId);

View File

@ -53,6 +53,11 @@ public class BatchStrategyDto implements Serializable {
*/
private Integer failRetryCount = 0;
/**
*
*/
private String retryStrategy;
public String getTenantId() {
return tenantId;
}
@ -116,4 +121,12 @@ public class BatchStrategyDto implements Serializable {
public void setFailRetryCount(Integer failRetryCount) {
this.failRetryCount = failRetryCount;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -112,6 +112,11 @@ public class AtuPlanInfoAddDto implements Serializable
*/
@ApiModelProperty("失败重试次数")
private Integer failRetryCount;
/**
* <br>
*/
@ApiModelProperty("重试策略")
private String retryStrategy;
/**
* ;0-1-<br>
*/
@ -338,4 +343,12 @@ public class AtuPlanInfoAddDto implements Serializable
public void setDeviceList(List<DeviceList> deviceList) {
this.deviceList = deviceList;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -147,6 +147,11 @@ public class AtuPlanInfoDetailDto implements Serializable
*/
@ApiModelProperty("失败重试次数")
private Integer failRetryCount;
/**
* <br>
*/
@ApiModelProperty("重试策略")
private String retryStrategy;
/**
* ;0-1-<br>
*/
@ -636,4 +641,12 @@ public class AtuPlanInfoDetailDto implements Serializable
public void setLastBatchScriptSumMap(Map<String, Integer> lastBatchScriptSumMap) {
this.lastBatchScriptSumMap = lastBatchScriptSumMap;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -115,6 +115,11 @@ public class AtuPlanInfoUpdateDto implements Serializable
*/
@ApiModelProperty("失败重试次数")
private Integer failRetryCount;
/**
* <br>
*/
@ApiModelProperty("重试策略")
private String retryStrategy;
/**
* ;0-1-<br>
*/
@ -357,4 +362,12 @@ public class AtuPlanInfoUpdateDto implements Serializable
public void setDeviceList(List<DeviceList> deviceList) {
this.deviceList = deviceList;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -180,6 +180,9 @@ public class AtuPlanTaskPageDto implements Serializable {
@ApiModelProperty("当前直播是否为接口用例")
private boolean apiCase = false;
@ApiModelProperty("总耗时")
private Long totalExecTake;
public boolean isApiCase() {
return apiCase;
}
@ -395,4 +398,12 @@ public class AtuPlanTaskPageDto implements Serializable {
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public Long getTotalExecTake() {
return totalExecTake;
}
public void setTotalExecTake(Long totalExecTake) {
this.totalExecTake = totalExecTake;
}
}

View File

@ -77,7 +77,10 @@ public class AtuTaskExecDto implements Serializable {
*
*/
private Integer failRetryNum;
/**
* <br>
*/
private String retryStrategy;
/**
* ID
*/
@ -207,4 +210,12 @@ public class AtuTaskExecDto implements Serializable {
public void setEnvId(String envId) {
this.envId = envId;
}
public String getRetryStrategy() {
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
}

View File

@ -46,6 +46,10 @@ public class AtuTaskExecResultDto implements Serializable {
* 1-2-3-4-5-6-
*/
private String status;
/**
*
*/
private boolean needRetry;
/**
*
@ -224,4 +228,12 @@ public class AtuTaskExecResultDto implements Serializable {
public void setDevicePerInfo(DevicePerInfo devicePerInfo) {
this.devicePerInfo = devicePerInfo;
}
public boolean isNeedRetry() {
return needRetry;
}
public void setNeedRetry(boolean needRetry) {
this.needRetry = needRetry;
}
}

View File

@ -0,0 +1,24 @@
package net.northking.cctp.executePlan.dto.planTask;
public class PlanTaskRecordDto {
private String taskId;
private long totalTake;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public long getTotalTake() {
return totalTake;
}
public void setTotalTake(long totalTake) {
this.totalTake = totalTake;
}
}

View File

@ -13,6 +13,7 @@ import net.northking.cctp.common.s3.NKFile;
import net.northking.cctp.common.s3.SimpleStorageService;
import net.northking.cctp.common.security.authentication.NKSecurityContext;
import net.northking.cctp.executePlan.api.service.AtuPlanInfoApiService;
import net.northking.cctp.executePlan.api.service.AtuPlanTaskApiService;
import net.northking.cctp.executePlan.api.service.MessageCenterService;
import net.northking.cctp.executePlan.api.third.feilang.service.FeiLangService;
import net.northking.cctp.executePlan.constants.MsgConstant;
@ -21,10 +22,7 @@ import net.northking.cctp.executePlan.constants.RabbitConstant;
import net.northking.cctp.executePlan.constants.RedisConstant;
import net.northking.cctp.executePlan.db.entity.*;
import net.northking.cctp.executePlan.db.service.*;
import net.northking.cctp.executePlan.dto.planBatch.AtuPlanBatchDetailDto;
import net.northking.cctp.executePlan.dto.planBatch.BatchAppInfoDto;
import net.northking.cctp.executePlan.dto.planBatch.BatchMobilePerformanceDto;
import net.northking.cctp.executePlan.dto.planBatch.MobileTaskPerformanceDto;
import net.northking.cctp.executePlan.dto.planBatch.*;
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanRunDto;
import net.northking.cctp.executePlan.enums.MobilePlatformEnum;
import net.northking.cctp.executePlan.feign.PublicFeignClient;
@ -68,6 +66,9 @@ public class PlanBatchTaskDataUpdateJob {
@Autowired
private AtuPlanTaskService planTaskService;
@Autowired
private AtuPlanTaskApiService planTaskApiService;
@Autowired
private AtuPlanInfoApiService planInfoApiService;
@ -267,6 +268,41 @@ public class PlanBatchTaskDataUpdateJob {
logger.debug("同步缓存中计划批次统计数据----end----");
}
/**
*
* @param planInfo
* @param planBatch
* @return
*/
private boolean failRetryCheck(AtuPlanInfo planInfo, AtuPlanBatch planBatch) {
if (planInfo.getFailRetry() && PlanConstant.TASK_RETRY_STRATEGY_PACKAGE.equals(planInfo.getRetryStrategy())) {
Object o = redisTemplate.opsForHash().get(RedisConstant.PLAN_BATCH_RETRY_COUNT, planBatch.getId());
if (o != null) {
int count = Integer.parseInt(o.toString());
logger.info("计划-批次【{}-{}】重试次数还剩下:{}次", planInfo.getPlanName(), planBatch.getBatch(), count);
if (count == 0) { // 重试已完成
redisTemplate.opsForHash().delete(RedisConstant.PLAN_BATCH_RETRY_COUNT, planBatch.getId());
return false;
}
// 查询批次下的失败任务
List<String> taskIds = planTaskService.queryAllFailIdList(planBatch.getId());
List<Object> resultIds = new ArrayList<>(taskIds);
BatchRetryDto dto = new BatchRetryDto();
dto.setTaskIdList(resultIds);
logger.info("计划-批次【{}-{}】需要重试的任务数量:{}", planInfo.getPlanName(), planBatch.getBatch(), taskIds.size());
if (!taskIds.isEmpty()) {
planTaskApiService.taskRetry(dto);
redisTemplate.opsForHash().put(RedisConstant.PLAN_BATCH_RETRY_COUNT, planBatch.getId(), String.valueOf(--count));
} else {
redisTemplate.opsForHash().delete(RedisConstant.PLAN_BATCH_RETRY_COUNT, planBatch.getId()); // 没有失败的任务清除redis信息不需要重试
return false;
}
return true;
}
}
return false;
}
private void saveDevicePerData(AtuPlanBatchDetailDto atuPlanBatchDetailDto) {
String batchId = atuPlanBatchDetailDto.getId();
String tenantId = atuPlanBatchDetailDto.getTenantId();
@ -459,6 +495,22 @@ public class PlanBatchTaskDataUpdateJob {
* @param planBatch
*/
private void handleEnd(AtuPlanInfo planInfo, AtuPlanBatchDetailDto planBatch) {
if (PlanConstant.BATCH_CANCEL_STATUS.equals(planBatch.getStatus())) { // 如果是取消,不需要执行收尾处理
return;
}
// 检查计划是否需要重试,如果需要并且是执行完成批次后再执行失败的任务,那么获取失败任务,批量重试。
if (PlanConstant.BATCH_FINISH_STATUS.equals(planBatch.getStatus()) && planInfo.getFailRetry()) {
boolean isRetry = false;
try {
isRetry = failRetryCheck(planInfo, planBatch);
} catch (Exception e) {
logger.error("批次{}下失败任务重试失败", planBatch.getId(), e);
}
if (isRetry) {
logger.info("计划需要对失败的任务进行重试...");
return;
}
}
// 计划是否被其他计划设为前置执行计划
List<String> planIdList = planInfoService.queryFollowUpPlanIdList(planInfo.getId());
if (CollUtil.isNotEmpty(planIdList)) {

View File

@ -45,6 +45,8 @@
<result column="is_fail_retry" jdbcType="BIT" property="failRetry"/>
<!-- 失败重试次数 -->
<result column="fail_retry_count" jdbcType="INTEGER" property="failRetryCount"/>
<!-- 失败重试策略 -->
<result column="retry_strategy" jdbcType="VARCHAR" property="retryStrategy"/>
<!-- 是否失败生成计划;0-1--->
<result column="is_fail_create_plan" jdbcType="BIT" property="failCreatePlan"/>
<!-- 最近执行时间 -->
@ -109,6 +111,7 @@
,mail_address
,is_fail_retry
,fail_retry_count
,retry_strategy
,is_fail_create_plan
,last_exec_time
,next_exec_time
@ -363,6 +366,9 @@
<if test="failRetryCount != null">
fail_retry_count,
</if>
<if test="retryStrategy != null">
retry_strategy,
</if>
<if test="failCreatePlan != null">
is_fail_create_plan,
</if>
@ -482,6 +488,9 @@
<if test="failRetry != null">
#{failRetry, jdbcType=BIT},
</if>
<if test="retryStrategy != null">
#{retryStrategy, jdbcType=VARCHAR},
</if>
<if test="failRetryCount != null">
#{failRetryCount, jdbcType=INTEGER},
</if>
@ -574,6 +583,7 @@
mail_address,
is_fail_retry,
fail_retry_count,
retry_strategy,
is_fail_create_plan,
last_exec_time,
next_exec_time,
@ -618,6 +628,7 @@
#{item.mailAddress, jdbcType=VARCHAR},
#{item.failRetry, jdbcType=BIT},
#{item.failRetryCount, jdbcType=INTEGER},
#{item.retryStrategy, jdbcType=VARCHAR},
#{item.failCreatePlan, jdbcType=BIT},
#{item.lastExecTime, jdbcType=TIMESTAMP},
#{item.nextExecTime, jdbcType=TIMESTAMP},
@ -701,6 +712,9 @@
<if test="failRetryCount != null">
fail_retry_count = #{failRetryCount, jdbcType=INTEGER},
</if>
<if test="retryStrategy != null">
retry_strategy = #{retryStrategy, jdbcType=VARCHAR},
</if>
<if test="failCreatePlan != null">
is_fail_create_plan = #{failCreatePlan, jdbcType=BIT},
</if>
@ -831,6 +845,9 @@
<if test="failRetryCount != null">
AND fail_retry_count = #{failRetryCount,jdbcType=INTEGER}
</if>
<if test="retryStrategy != null">
AND retry_strategy=#{retryStrategy,jdbcType=VARCHAR}
</if>
<if test="failCreatePlan != null">
AND is_fail_create_plan = #{failCreatePlan,jdbcType=BIT}
</if>
@ -958,6 +975,9 @@
<if test="failRetryCount != null">
AND fail_retry_count=#{failRetryCount,jdbcType=INTEGER}
</if>
<if test="retryStrategy != null">
AND retry_strategy=#{retryStrategy,jdbcType=VARCHAR}
</if>
<if test="failCreatePlan != null">
AND is_fail_create_plan=#{failCreatePlan,jdbcType=BIT}
</if>

View File

@ -0,0 +1,360 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- Copyright (c) 京北方信息技术股份有限公司 Corporation 2024 . All rights reserved. -->
<!-- Mybatis数据库持久层底层映射文件任务执行记录表 -->
<!-- version: 1.0 -->
<!-- author: maven-cctp-plugin -->
<!-- date: 2024-10-16 17:02:48 -->
<mapper namespace="net.northking.cctp.executePlan.db.dao.AtuPlanTaskRecordDao">
<resultMap id="BaseResultMap" type="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
<!-- 记录id -->
<id column="id" jdbcType="VARCHAR" property="id"/>
<!-- 任务id -->
<result column="task_id" jdbcType="VARCHAR" property="taskId"/>
<!-- 批次id -->
<result column="batch_id" jdbcType="VARCHAR" property="batchId"/>
<!-- 执行序号 -->
<result column="exec_idx" jdbcType="INTEGER" property="execIdx"/>
<!-- 开始时间 -->
<result column="start_time" jdbcType="BIGINT" property="startTime"/>
<!-- 结束时间 -->
<result column="end_time" jdbcType="BIGINT" property="endTime"/>
<!-- 执行类型0-正常执行|1-自动重试|2-手动重试 -->
<result column="execute_type" jdbcType="VARCHAR" property="executeType"/>
<!-- 状态 -->
<result column="status" jdbcType="VARCHAR" property="status"/>
<!-- 错误信息 -->
<result column="error_msg" jdbcType="LONGVARCHAR" property="errorMsg"/>
<!-- 视频地址 -->
<result column="video_url" jdbcType="VARCHAR" property="videoUrl"/>
<!-- 执行结果文件 -->
<result column="exec_result_file" jdbcType="VARCHAR" property="execResultFile"/>
</resultMap>
<sql id="Base_Column_List">
id
,task_id
,batch_id
,exec_idx
,start_time
,end_time
,execute_type
,status
,error_msg
,video_url
,exec_result_file
</sql>
<sql id="Table_Name">
${defaultSchema}.atu_plan_task_record
</sql>
<select id="findByPrimaryKey" parameterType="String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from
<include refid="Table_Name"/>
where id = #{id,jdbcType=VARCHAR}
</select>
<select id="findByPrimaryKeys" parameterType="java.util.List">
select
<include refid="Base_Column_List"/>
from
<include refid="Table_Name"/>
where id in
<foreach collection="list" item="idItem" open="(" separator="," close=")">
#{idItem, jdbcType=VARCHAR}
</foreach>
</select>
<delete id="deleteByPrimaryKey" parameterType="String">
delete from
<include refid="Table_Name"/>
where id = #{id,jdbcType=VARCHAR}
</delete>
<delete id="deleteByPrimaryKeys" parameterType="String">
delete from
<include refid="Table_Name"/>
where id in
<foreach collection="list" item="idItem" open="(" separator="," close=")">
#{idItem, jdbcType=VARCHAR}
</foreach>
</delete>
<delete id="deleteByExample" parameterType="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
delete from
<include refid="Table_Name"/>
<trim prefix="WHERE" prefixOverrides="AND" >
<choose>
<when test="id != null">
id = #{id,jdbcType=VARCHAR}
</when>
</choose>
<if test="id != null">
AND id=#{id,jdbcType=VARCHAR}
</if>
<if test="taskId != null">
AND task_id=#{taskId,jdbcType=VARCHAR}
</if>
<if test="batchId != null">
AND batch_id=#{batchId,jdbcType=VARCHAR}
</if>
<if test="execIdx != null">
AND exec_idx=#{execIdx,jdbcType=INTEGER}
</if>
<if test="startTime != null">
AND start_time=#{startTime,jdbcType=BIGINT}
</if>
<if test="endTime != null">
AND end_time=#{endTime,jdbcType=BIGINT}
</if>
<if test="executeType != null">
AND execute_type=#{executeType,jdbcType=VARCHAR}
</if>
<if test="status != null">
AND status=#{status,jdbcType=VARCHAR}
</if>
<if test="errorMsg != null">
AND error_msg=#{errorMsg,jdbcType=LONGVARCHAR}
</if>
<if test="videoUrl != null">
AND video_url=#{videoUrl,jdbcType=VARCHAR}
</if>
<if test="execResultFile != null">
AND exec_result_file=#{execResultFile,jdbcType=VARCHAR}
</if>
</trim>
</delete>
<insert id="insert" parameterType="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
insert into
<include refid="Table_Name"/>
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="taskId != null">
task_id,
</if>
<if test="batchId != null">
batch_id,
</if>
<if test="execIdx != null">
exec_idx,
</if>
<if test="startTime != null">
start_time,
</if>
<if test="endTime != null">
end_time,
</if>
<if test="executeType != null">
execute_type,
</if>
<if test="status != null">
status,
</if>
<if test="errorMsg != null">
error_msg,
</if>
<if test="videoUrl != null">
video_url,
</if>
<if test="execResultFile != null">
exec_result_file,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id, jdbcType=VARCHAR},
</if>
<if test="taskId != null">
#{taskId, jdbcType=VARCHAR},
</if>
<if test="batchId != null">
#{batchId, jdbcType=VARCHAR},
</if>
<if test="execIdx != null">
#{execIdx, jdbcType=INTEGER},
</if>
<if test="startTime != null">
#{startTime, jdbcType=BIGINT},
</if>
<if test="endTime != null">
#{endTime, jdbcType=BIGINT},
</if>
<if test="executeType != null">
#{executeType, jdbcType=VARCHAR},
</if>
<if test="status != null">
#{status, jdbcType=VARCHAR},
</if>
<if test="errorMsg != null">
#{errorMsg, jdbcType=LONGVARCHAR},
</if>
<if test="videoUrl != null">
#{videoUrl, jdbcType=VARCHAR},
</if>
<if test="execResultFile != null">
#{execResultFile, jdbcType=VARCHAR},
</if>
</trim>
</insert>
<insert id="insertByBatch" parameterType="java.util.List">
insert into
<include refid="Table_Name"/>
<trim prefix="(" suffix=")" suffixOverrides=",">
id,
task_id,
batch_id,
exec_idx,
start_time,
end_time,
execute_type,
status,
error_msg,
video_url,
exec_result_file,
</trim>
values
<foreach collection="list" item="item" index="index" separator=",">
<trim prefix="(" suffix=")" suffixOverrides=",">
#{item.id, jdbcType=VARCHAR},
#{item.taskId, jdbcType=VARCHAR},
#{item.batchId, jdbcType=VARCHAR},
#{item.execIdx, jdbcType=INTEGER},
#{item.startTime, jdbcType=BIGINT},
#{item.endTime, jdbcType=BIGINT},
#{item.executeType, jdbcType=VARCHAR},
#{item.status, jdbcType=VARCHAR},
#{item.errorMsg, jdbcType=LONGVARCHAR},
#{item.videoUrl, jdbcType=VARCHAR},
#{item.execResultFile, jdbcType=VARCHAR},
</trim>
</foreach>
</insert>
<update id="updateByPrimaryKey" parameterType="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
update
<include refid="Table_Name"/>
<set>
<if test="taskId != null">
task_id = #{taskId, jdbcType=VARCHAR},
</if>
<if test="batchId != null">
batch_id = #{batchId, jdbcType=VARCHAR},
</if>
<if test="execIdx != null">
exec_idx = #{execIdx, jdbcType=INTEGER},
</if>
<if test="startTime != null">
start_time = #{startTime, jdbcType=BIGINT},
</if>
<if test="endTime != null">
end_time = #{endTime, jdbcType=BIGINT},
</if>
<if test="executeType != null">
execute_type = #{executeType, jdbcType=VARCHAR},
</if>
<if test="status != null">
status = #{status, jdbcType=VARCHAR},
</if>
<if test="errorMsg != null">
error_msg = #{errorMsg, jdbcType=LONGVARCHAR},
</if>
<if test="videoUrl != null">
video_url = #{videoUrl, jdbcType=VARCHAR},
</if>
<if test="execResultFile != null">
exec_result_file = #{execResultFile, jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<select id="query" resultMap="BaseResultMap" parameterType="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
select
<include refid="Base_Column_List" />
from
<include refid="Table_Name"/>
<trim prefix="WHERE" prefixOverrides="AND" >
<if test="id != null">
AND id = #{id,jdbcType=VARCHAR}
</if>
<if test="taskId != null">
AND task_id = #{taskId,jdbcType=VARCHAR}
</if>
<if test="batchId != null">
AND batch_id = #{batchId,jdbcType=VARCHAR}
</if>
<if test="execIdx != null">
AND exec_idx = #{execIdx,jdbcType=INTEGER}
</if>
<if test="startTime != null">
AND start_time = #{startTime,jdbcType=BIGINT}
</if>
<if test="endTime != null">
AND end_time = #{endTime,jdbcType=BIGINT}
</if>
<if test="executeType != null">
AND execute_type = #{executeType,jdbcType=VARCHAR}
</if>
<if test="status != null">
AND status = #{status,jdbcType=VARCHAR}
</if>
<if test="errorMsg != null">
AND error_msg = #{errorMsg,jdbcType=LONGVARCHAR}
</if>
<if test="videoUrl != null">
AND video_url = #{videoUrl,jdbcType=VARCHAR}
</if>
<if test="execResultFile != null">
AND exec_result_file = #{execResultFile,jdbcType=VARCHAR}
</if>
</trim>
</select>
<select id="queryCount" resultType="java.lang.Long" parameterType="net.northking.cctp.executePlan.db.entity.AtuPlanTaskRecord">
select count(*) from
<include refid="Table_Name"/>
<trim prefix="WHERE" prefixOverrides="AND" >
<if test="id != null">
AND id=#{id,jdbcType=VARCHAR}
</if>
<if test="taskId != null">
AND task_id=#{taskId,jdbcType=VARCHAR}
</if>
<if test="batchId != null">
AND batch_id=#{batchId,jdbcType=VARCHAR}
</if>
<if test="execIdx != null">
AND exec_idx=#{execIdx,jdbcType=INTEGER}
</if>
<if test="startTime != null">
AND start_time=#{startTime,jdbcType=BIGINT}
</if>
<if test="endTime != null">
AND end_time=#{endTime,jdbcType=BIGINT}
</if>
<if test="executeType != null">
AND execute_type=#{executeType,jdbcType=VARCHAR}
</if>
<if test="status != null">
AND status=#{status,jdbcType=VARCHAR}
</if>
<if test="errorMsg != null">
AND error_msg=#{errorMsg,jdbcType=LONGVARCHAR}
</if>
<if test="videoUrl != null">
AND video_url=#{videoUrl,jdbcType=VARCHAR}
</if>
<if test="execResultFile != null">
AND exec_result_file=#{execResultFile,jdbcType=VARCHAR}
</if>
</trim>
</select>
</mapper>

View File

@ -49,6 +49,8 @@
<result column="is_fail_retry" jdbcType="BIT" property="failRetry"/>
<!-- 失败重试次数 -->
<result column="fail_retry_count" jdbcType="INTEGER" property="failRetryCount"/>
<!-- 失败重试策略 -->
<result column="retry_strategy" jdbcType="VARCHAR" property="retryStrategy"/>
<!-- 是否失败生成计划;0-1--->
<result column="is_fail_create_plan" jdbcType="BIT" property="failCreatePlan"/>
<!-- 最近执行时间 -->
@ -130,6 +132,7 @@
,mail_address
,is_fail_retry
,fail_retry_count
,retry_strategy
,is_fail_create_plan
,last_exec_time
,next_exec_time
@ -210,6 +213,9 @@
<if test="failRetryCount != null">
AND fail_retry_count = #{failRetryCount,jdbcType=INTEGER}
</if>
<if test="retryStrategy != null">
AND retry_strategy = #{retryStrategy,jdbcType=VARCHAR}
</if>
<if test="failCreatePlan != null">
AND is_fail_create_plan = #{failCreatePlan,jdbcType=BIT}
</if>
@ -288,6 +294,7 @@
,mail_address
,is_fail_retry
,fail_retry_count
,retry_strategy
,is_fail_create_plan
,last_exec_time
,next_exec_time
@ -418,6 +425,7 @@
,mail_address
,is_fail_retry
,fail_retry_count
,retry_strategy
,is_fail_create_plan
,last_exec_time
,next_exec_time

View File

@ -329,4 +329,8 @@
where batch_id in (select id from atu_plan_batch where plan_id = #{planId})
LIMIT #{num}
</delete>
<select id="queryAllFailIdList" resultType="java.lang.String">
select id from <include refid="Table_Name"/> where batch_id = #{batchId} and status in ("3", "4", "6")
</select>
</mapper>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- Copyright (c) 京北方信息技术股份有限公司 Corporation 2024 . All rights reserved. -->
<!-- Mybatis数据库持久层业务层映射文件任务执行记录表 -->
<!-- version: 1.0 -->
<!-- author: maven-cctp-plugin -->
<!-- date: 2024-10-16 17:02:48 -->
<mapper namespace="net.northking.cctp.executePlan.db.dao.AtuPlanTaskRecordDao">
<!-- 请在本文件内添加自定义SQL语句 -->
<select id="queryTotalTake" parameterType="java.util.List" resultType="net.northking.cctp.executePlan.dto.planTask.PlanTaskRecordDto">
SELECT task_id AS taskId, sum(take) AS totalTake FROM
(
SELECT id, task_id, (end_time - start_time) AS take
FROM <include refid="Table_Name" />
WHERE
task_id IN
<foreach collection="taskIds" item="id" open="(" separator="," close=")">
#{id, jdbcType=VARCHAR}
</foreach>
AND end_time IS NOT NULL
) AS temp
GROUP BY task_id
</select>
</mapper>

View File

@ -0,0 +1,22 @@
-- 2024.10.17 增加表atu_plan_task_record
CREATE TABLE `atu_plan_task_record` (
`id` VARCHAR(32) NOT NULL COMMENT '记录id' COLLATE 'utf8mb4_general_ci',
`task_id` VARCHAR(32) NULL DEFAULT NULL COMMENT '任务id' COLLATE 'utf8mb4_general_ci',
`batch_id` VARCHAR(32) NULL DEFAULT NULL COMMENT '批次id' COLLATE 'utf8mb4_general_ci',
`exec_idx` INT(11) NULL DEFAULT '1' COMMENT '执行序号',
`start_time` BIGINT(20) NULL DEFAULT NULL COMMENT '开始时间',
`end_time` BIGINT(20) NULL DEFAULT NULL COMMENT '结束时间',
`execute_type` VARCHAR(10) NULL DEFAULT '0' COMMENT '执行类型0-正常执行|1-自动重试|2-手动重试' COLLATE 'utf8mb4_general_ci',
`status` VARCHAR(10) NULL DEFAULT '0' COMMENT '状态' COLLATE 'utf8mb4_general_ci',
`error_msg` TEXT(65535) NULL DEFAULT NULL COMMENT '错误信息' COLLATE 'utf8mb4_general_ci',
`video_url` VARCHAR(255) NULL DEFAULT NULL COMMENT '视频地址' COLLATE 'utf8mb4_general_ci',
`exec_result_file` VARCHAR(255) NULL DEFAULT NULL COMMENT '执行结果文件' COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COMMENT='任务执行记录表'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
-- 2024.10.17 修改表atu_plan_info 增加字段restry_strategy重试策略
ALTER TABLE `atu_plan_info`
ADD COLUMN `retry_strategy` VARCHAR(10) NULL DEFAULT NULL COMMENT '重试策略 1-失败任务打包重试|2-任务失败立刻重试' COLLATE 'utf8_general_ci' AFTER `fail_retry_count`;