fix:执行计划
问题:在有些特殊时间节点下,由于定时任务更新批次信息和批量重试的时候存在同时操作的问题,导致队列会被删除 解决:修改锁获取的先后逻辑。对于批次信息、状态处理的逻辑都需要获取锁进行操作,降低由于时间差导致的数据异常。hz_1122
parent
5d95eda546
commit
8beaa4b87a
|
@ -5,20 +5,26 @@
|
||||||
package net.northking.cctp.executePlan.api;
|
package net.northking.cctp.executePlan.api;
|
||||||
|
|
||||||
import cn.gjing.tools.auth.annotation.RequiredPermissions;
|
import cn.gjing.tools.auth.annotation.RequiredPermissions;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import net.northking.cctp.common.exception.PlatformRuntimeException;
|
||||||
import net.northking.cctp.common.http.ResultWrapper;
|
import net.northking.cctp.common.http.ResultWrapper;
|
||||||
import net.northking.cctp.common.security.authentication.NKSecurityContext;
|
import net.northking.cctp.common.security.authentication.NKSecurityContext;
|
||||||
import net.northking.cctp.executePlan.api.service.AtuPlanBatchApiService;
|
import net.northking.cctp.executePlan.api.service.AtuPlanBatchApiService;
|
||||||
import net.northking.cctp.executePlan.api.service.AtuPlanInfoApiService;
|
import net.northking.cctp.executePlan.api.service.AtuPlanInfoApiService;
|
||||||
import net.northking.cctp.executePlan.api.service.AtuPlanTaskApiService;
|
import net.northking.cctp.executePlan.api.service.AtuPlanTaskApiService;
|
||||||
import net.northking.cctp.executePlan.constants.PlanConstant;
|
import net.northking.cctp.executePlan.constants.PlanConstant;
|
||||||
|
import net.northking.cctp.executePlan.constants.RedisConstant;
|
||||||
|
import net.northking.cctp.executePlan.db.entity.AtuPlanBatch;
|
||||||
|
import net.northking.cctp.executePlan.db.entity.AtuPlanTask;
|
||||||
import net.northking.cctp.executePlan.dto.planBatch.BatchRetryDto;
|
import net.northking.cctp.executePlan.dto.planBatch.BatchRetryDto;
|
||||||
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanInfoDetailDto;
|
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanInfoDetailDto;
|
||||||
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanRunDto;
|
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanRunDto;
|
||||||
import net.northking.cctp.executePlan.dto.planTask.AtuPlanTaskDetailDto;
|
import net.northking.cctp.executePlan.dto.planTask.AtuPlanTaskDetailDto;
|
||||||
import net.northking.cctp.executePlan.dto.planTask.AtuTaskSendBugDto;
|
import net.northking.cctp.executePlan.dto.planTask.AtuTaskSendBugDto;
|
||||||
|
import net.northking.cctp.executePlan.exception.ExecPlanError;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -27,7 +33,9 @@ import org.springframework.integration.redis.util.RedisLockRegistry;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行计划表 => Restful 类型 HTTP/HTTPS 接口
|
* 执行计划表 => Restful 类型 HTTP/HTTPS 接口
|
||||||
|
@ -205,7 +213,28 @@ public class AtuPlanInfoRestfulCtrl {
|
||||||
logger.info("start taskRetry: retryDto =======> " + JSONUtil.toJsonStr(retryDto));
|
logger.info("start taskRetry: retryDto =======> " + JSONUtil.toJsonStr(retryDto));
|
||||||
|
|
||||||
ResultWrapper<Boolean> wrapper = new ResultWrapper<>();
|
ResultWrapper<Boolean> wrapper = new ResultWrapper<>();
|
||||||
Boolean result = taskApiService.taskRetry(retryDto);
|
Boolean result = false;
|
||||||
|
if (retryDto.getTaskIdList() != null && !retryDto.getTaskIdList().isEmpty()) {
|
||||||
|
logger.debug("查询需要重试的任务信息");
|
||||||
|
List<AtuPlanTask> planTaskList = taskApiService.findByPrimaryKeys(retryDto.getTaskIdList());
|
||||||
|
logger.debug("查询需要重试的任务信息数量:{}", planTaskList.size());
|
||||||
|
if (CollUtil.isEmpty(planTaskList)) {
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.TASK_INFO_IS_NULL);
|
||||||
|
}
|
||||||
|
AtuPlanTask firstFailTask = planTaskList.get(0);
|
||||||
|
AtuPlanBatch planBatch = batchApiService.findByPrimaryKey(firstFailTask.getBatchId());
|
||||||
|
// 加个锁,当选择的任务量比较多的时候,需要时间进行处理
|
||||||
|
Lock lock = redisLockRegistry.obtain(String.format("%s%s", RedisConstant.PLAN_BATCH_RETRY_LOCK_PRE, planBatch.getId()));
|
||||||
|
if (!lock.tryLock()) {
|
||||||
|
// 获取不到锁,正在处理重试
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.BATCH_IS_DEALING_WITH_RETRY);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result = taskApiService.taskRetry(retryDto);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("end taskRetry");
|
logger.info("end taskRetry");
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,14 @@ public interface AtuPlanTaskApiService extends ExcelService
|
||||||
*/
|
*/
|
||||||
AtuPlanTask findByPrimaryKey(String id);
|
AtuPlanTask findByPrimaryKey(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据多个主键查询任务信息
|
||||||
|
*
|
||||||
|
* @param keys 主键集合
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<AtuPlanTask> findByPrimaryKeys(List<Object> keys);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务重试
|
* 任务重试
|
||||||
* @param retryDto 任务id
|
* @param retryDto 任务id
|
||||||
|
|
|
@ -1470,6 +1470,11 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
|
||||||
return this.atuPlanTaskService.findByPrimaryKey(id);
|
return this.atuPlanTaskService.findByPrimaryKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AtuPlanTask> findByPrimaryKeys(List<Object> keys) {
|
||||||
|
return this.atuPlanTaskService.findByPrimaryKeys(keys);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean taskRetry(BatchRetryDto retryDto) {
|
public Boolean taskRetry(BatchRetryDto retryDto) {
|
||||||
|
@ -1486,274 +1491,264 @@ public class AtuPlanTaskApiServiceImpl extends AbstractExcelService<AtuPlanTask>
|
||||||
PlanConstant.BATCH_EXECUTING_STATUS.equals(planBatch.getStatus())) {
|
PlanConstant.BATCH_EXECUTING_STATUS.equals(planBatch.getStatus())) {
|
||||||
throw new PlatformRuntimeException(ExecPlanError.BATCH_NOT_FINISH);
|
throw new PlatformRuntimeException(ExecPlanError.BATCH_NOT_FINISH);
|
||||||
}
|
}
|
||||||
// 加个锁,当选择的任务量比较多的时候,需要时间进行处理
|
logger.debug("根据批次编号[{}]查询计划信息", firstFailTask.getBatchId());
|
||||||
Lock lock = redisLockRegistry.obtain(String.format("%s%s", RedisConstant.PLAN_BATCH_RETRY_LOCK_PRE, planBatch.getId()));
|
AtuPlanInfo planInfo = atuPlanInfoApiService.findByBatchId(firstFailTask.getBatchId());
|
||||||
if (!lock.tryLock()) {
|
if (planInfo == null) {
|
||||||
// 获取不到锁,正在处理重试
|
throw new PlatformRuntimeException(ExecPlanError.PLAN_IS_NULL);
|
||||||
throw new PlatformRuntimeException(ExecPlanError.BATCH_IS_DEALING_WITH_RETRY);
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
logger.debug("根据批次编号[{}]查询计划信息", firstFailTask.getBatchId());
|
|
||||||
AtuPlanInfo planInfo = atuPlanInfoApiService.findByBatchId(firstFailTask.getBatchId());
|
|
||||||
if (planInfo == null) {
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.PLAN_IS_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("更新计划和批次状态");
|
logger.debug("更新计划和批次状态");
|
||||||
String planStatus = "";
|
String planStatus = "";
|
||||||
if (planBatch.getTaskTotal() > retryDto.getTaskIdList().size()) {
|
if (planBatch.getTaskTotal() > retryDto.getTaskIdList().size()) {
|
||||||
logger.debug("部分任务重试,批次状态为:{},计划状态为:{}", PlanConstant.BATCH_EXECUTING_STATUS,
|
logger.debug("部分任务重试,批次状态为:{},计划状态为:{}", PlanConstant.BATCH_EXECUTING_STATUS,
|
||||||
PlanConstant.PLAN_EXECUTING_STATUS);
|
PlanConstant.PLAN_EXECUTING_STATUS);
|
||||||
planBatch.setStatus(PlanConstant.BATCH_EXECUTING_STATUS);
|
planBatch.setStatus(PlanConstant.BATCH_EXECUTING_STATUS);
|
||||||
planStatus = PlanConstant.PLAN_EXECUTING_STATUS;
|
planStatus = PlanConstant.PLAN_EXECUTING_STATUS;
|
||||||
} else {
|
} else {
|
||||||
logger.debug("全部任务重试,批次状态为:{},计划状态为:{}", PlanConstant.BATCH_WAITING_STATUS,
|
logger.debug("全部任务重试,批次状态为:{},计划状态为:{}", PlanConstant.BATCH_WAITING_STATUS,
|
||||||
PlanConstant.PLAN_WAITING_STATUS);
|
PlanConstant.PLAN_WAITING_STATUS);
|
||||||
planBatch.setStatus(PlanConstant.BATCH_WAITING_STATUS);
|
planBatch.setStatus(PlanConstant.BATCH_WAITING_STATUS);
|
||||||
planStatus = PlanConstant.PLAN_WAITING_STATUS;
|
planStatus = PlanConstant.PLAN_WAITING_STATUS;
|
||||||
|
}
|
||||||
|
List<String> deletedFilePath = new ArrayList<>();
|
||||||
|
List<String> taskIds = new ArrayList<>();
|
||||||
|
planTaskList.forEach(task -> {
|
||||||
|
logger.info("普通脚本任务id:{},执行结果文件:{}", task.getId(), task.getExecResultFile());
|
||||||
|
taskIds.add(task.getId());
|
||||||
|
String execResultFile = task.getExecResultFile();
|
||||||
|
if (StringUtils.isNotBlank(execResultFile)) {
|
||||||
|
deletedFilePath.add(execResultFile);
|
||||||
|
getActualImagePath(deletedFilePath, execResultFile);
|
||||||
}
|
}
|
||||||
List<String> deletedFilePath = new ArrayList<>();
|
String perDataPath = task.getPerDataPath();
|
||||||
List<String> taskIds = new ArrayList<>();
|
if (StringUtils.isNotBlank(perDataPath)) {
|
||||||
planTaskList.forEach(task -> {
|
deletedFilePath.add("/" + MinioPathUtils.idToPath(perDataPath)[1]);
|
||||||
logger.info("普通脚本任务id:{},执行结果文件:{}", task.getId(), task.getExecResultFile());
|
}
|
||||||
taskIds.add(task.getId());
|
String videoUrl = task.getVideoUrl();
|
||||||
String execResultFile = task.getExecResultFile();
|
if (StringUtils.isNotBlank(videoUrl)) {
|
||||||
|
deletedFilePath.add("/" + MinioPathUtils.idToPath(videoUrl)[1]);
|
||||||
|
}
|
||||||
|
// 场景用例脚本json是单独的需要删除
|
||||||
|
if (task.getCaseType().equals("5")) {
|
||||||
|
deletedFilePath.add("/" + MinioPathUtils.idToPath(task.getScriptJson())[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!CollectionUtils.isEmpty(taskIds)) {
|
||||||
|
List<AtuPlanSceneCaseTask> atuPlanSceneCaseTaskList = atuPlanSceneCaseTaskService.querySceneCaseTasksByTaskIds(taskIds);
|
||||||
|
atuPlanSceneCaseTaskList.forEach(atuPlanSceneCaseTask -> {
|
||||||
|
logger.info("场景任务id:{},节点任务id:{},执行结果文件:{}", atuPlanSceneCaseTask.getTaskId(), atuPlanSceneCaseTask.getId(), atuPlanSceneCaseTask.getExecResultFile());
|
||||||
|
String videoUrl = atuPlanSceneCaseTask.getVideoUrl();
|
||||||
|
if (StringUtils.isNotBlank(videoUrl)) {
|
||||||
|
deletedFilePath.add("/" + MinioPathUtils.idToPath(videoUrl)[1]);
|
||||||
|
}
|
||||||
|
String perDataPath = atuPlanSceneCaseTask.getPerDataPath();
|
||||||
|
if (StringUtils.isNotBlank(perDataPath)) {
|
||||||
|
deletedFilePath.add("/" + MinioPathUtils.idToPath(perDataPath)[1]);
|
||||||
|
}
|
||||||
|
String execResultFile = atuPlanSceneCaseTask.getExecResultFile();
|
||||||
if (StringUtils.isNotBlank(execResultFile)) {
|
if (StringUtils.isNotBlank(execResultFile)) {
|
||||||
deletedFilePath.add(execResultFile);
|
deletedFilePath.add(execResultFile);
|
||||||
getActualImagePath(deletedFilePath, execResultFile);
|
getActualImagePath(deletedFilePath, execResultFile);
|
||||||
}
|
}
|
||||||
String perDataPath = task.getPerDataPath();
|
|
||||||
if (StringUtils.isNotBlank(perDataPath)) {
|
|
||||||
deletedFilePath.add("/" + MinioPathUtils.idToPath(perDataPath)[1]);
|
|
||||||
}
|
|
||||||
String videoUrl = task.getVideoUrl();
|
|
||||||
if (StringUtils.isNotBlank(videoUrl)) {
|
|
||||||
deletedFilePath.add("/" + MinioPathUtils.idToPath(videoUrl)[1]);
|
|
||||||
}
|
|
||||||
// 场景用例脚本json是单独的需要删除
|
|
||||||
if (task.getCaseType().equals("5")) {
|
|
||||||
deletedFilePath.add("/" + MinioPathUtils.idToPath(task.getScriptJson())[1]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (!CollectionUtils.isEmpty(taskIds)) {
|
|
||||||
List<AtuPlanSceneCaseTask> atuPlanSceneCaseTaskList = atuPlanSceneCaseTaskService.querySceneCaseTasksByTaskIds(taskIds);
|
|
||||||
atuPlanSceneCaseTaskList.forEach(atuPlanSceneCaseTask -> {
|
|
||||||
logger.info("场景任务id:{},节点任务id:{},执行结果文件:{}", atuPlanSceneCaseTask.getTaskId(), atuPlanSceneCaseTask.getId(), atuPlanSceneCaseTask.getExecResultFile());
|
|
||||||
String videoUrl = atuPlanSceneCaseTask.getVideoUrl();
|
|
||||||
if (StringUtils.isNotBlank(videoUrl)) {
|
|
||||||
deletedFilePath.add("/" + MinioPathUtils.idToPath(videoUrl)[1]);
|
|
||||||
}
|
|
||||||
String perDataPath = atuPlanSceneCaseTask.getPerDataPath();
|
|
||||||
if (StringUtils.isNotBlank(perDataPath)) {
|
|
||||||
deletedFilePath.add("/" + MinioPathUtils.idToPath(perDataPath)[1]);
|
|
||||||
}
|
|
||||||
String execResultFile = atuPlanSceneCaseTask.getExecResultFile();
|
|
||||||
if (StringUtils.isNotBlank(execResultFile)) {
|
|
||||||
deletedFilePath.add(execResultFile);
|
|
||||||
getActualImagePath(deletedFilePath, execResultFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!CollectionUtils.isEmpty(deletedFilePath)) {
|
|
||||||
AssociatedFilesDto associatedFilesDto = new AssociatedFilesDto();
|
|
||||||
associatedFilesDto.setObjId("-1");
|
|
||||||
associatedFilesDto.setFileIds(deletedFilePath);
|
|
||||||
attachmentFeignClient.associatedFiles(associatedFilesDto);
|
|
||||||
}
|
|
||||||
planBatchApiService.updateByEntity(planBatch);
|
|
||||||
atuPlanInfoApiService.updateStatusByLastBatchId(planBatch.getId(), planStatus);
|
|
||||||
|
|
||||||
logger.info("查询计划数据集中未被选择的意图数据");
|
|
||||||
Set<String> scriptIdSet = new HashSet<>();
|
|
||||||
Map<String, List<String>> envScriptMap = new HashMap<>();
|
|
||||||
Map<String, List<AtuPlanTask>> envScriptTaskMap = new HashMap<>();
|
|
||||||
List<String> taskIdList = new ArrayList<>();
|
|
||||||
for (AtuPlanTask planTask : planTaskList) {
|
|
||||||
taskIdList.add(planTask.getId());
|
|
||||||
scriptIdSet.add(planTask.getScriptId());
|
|
||||||
List<String> scriptIdList = new ArrayList<>();
|
|
||||||
if (envScriptMap.containsKey(planTask.getEnvId())) {
|
|
||||||
scriptIdList = envScriptMap.get(planTask.getEnvId());
|
|
||||||
}
|
|
||||||
scriptIdList.add(planTask.getScriptId());
|
|
||||||
envScriptMap.put(planTask.getEnvId(), scriptIdList);
|
|
||||||
String key = planTask.getEnvId() + "-" + planTask.getScriptId();
|
|
||||||
List<AtuPlanTask> envScriptTaskList = new ArrayList<>();
|
|
||||||
if (envScriptTaskMap.containsKey(key)) {
|
|
||||||
envScriptTaskList = envScriptTaskMap.get(key);
|
|
||||||
}
|
|
||||||
envScriptTaskList.add(planTask);
|
|
||||||
envScriptTaskMap.put(key, envScriptTaskList);
|
|
||||||
}
|
|
||||||
logger.debug("获取最新的输入项数据");
|
|
||||||
Map<String, String> taskParamsMap = getRetryTaskInputInfo(envScriptTaskMap, envScriptMap);
|
|
||||||
logger.debug("最新输入项数据大小:{}", taskParamsMap.size());
|
|
||||||
|
|
||||||
logger.debug("start 初始化批次缓存数据");
|
|
||||||
taskRetryInitCache(taskIdList, planBatch);
|
|
||||||
logger.debug("end 初始化批次缓存数据");
|
|
||||||
|
|
||||||
logger.debug("查询脚本最新数据");
|
|
||||||
logger.debug("脚本数量:{}", scriptIdSet.size());
|
|
||||||
Map<String, AtuScriptDetailDto> scriptMap = queryScriptDetailMap(scriptIdSet);
|
|
||||||
logger.debug("脚本最新信息数量:{}", scriptMap.size());
|
|
||||||
|
|
||||||
Map<String, Object> caseTypeMap = new HashMap<>();
|
|
||||||
caseTypeMap.put("hasPc", false);
|
|
||||||
caseTypeMap.put("hasMob", false);
|
|
||||||
caseTypeMap.put("hasInterface", false);
|
|
||||||
for (AtuPlanTask planTask : planTaskList) {
|
|
||||||
String status = planTask.getStatus();
|
|
||||||
logger.debug("原任务状态为: {}", status);
|
|
||||||
// 判断任务是否开始执行
|
|
||||||
if (PlanConstant.TASK_WAIT_EXECUTE_STATUS.equals(planTask.getStatus()) ||
|
|
||||||
PlanConstant.TASK_START_EXECUTE_STATUS.equals(planTask.getStatus())) {
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.TASK_NOT_FINISH);
|
|
||||||
}
|
|
||||||
logger.debug("修改任务脚本为最新脚本信息");
|
|
||||||
if (scriptMap.containsKey(planTask.getScriptId())) {
|
|
||||||
AtuScriptDetailDto atuScriptDetailDto = scriptMap.get(planTask.getScriptId());
|
|
||||||
planTask.setVersionId(atuScriptDetailDto.getVersionId());
|
|
||||||
planTask.setVersionName(atuScriptDetailDto.getVersionName());
|
|
||||||
planTask.setScriptName(atuScriptDetailDto.getScriptName());
|
|
||||||
planTask.setScriptJson(atuScriptDetailDto.getScriptPath());
|
|
||||||
planTask.setAppId(queryAppId(planInfo.getId(), atuScriptDetailDto.getPlatformType(),
|
|
||||||
atuScriptDetailDto.getAppPackage(), atuScriptDetailDto.getScriptType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("生成任务执行信息");
|
|
||||||
AtuTaskExecDto taskExecDto = new AtuTaskExecDto();
|
|
||||||
BeanUtil.copyProperties(planInfo, taskExecDto);
|
|
||||||
taskExecDto.setPlanId(planInfo.getId());
|
|
||||||
taskExecDto.setFailRetryNum(planInfo.getFailRetryCount());
|
|
||||||
taskExecDto.setBatchId(planTask.getBatchId());
|
|
||||||
taskExecDto.setTaskId(planTask.getId());
|
|
||||||
taskExecDto.setCaseId(planTask.getCaseId());
|
|
||||||
taskExecDto.setEnvId(planTask.getEnvId());
|
|
||||||
String type = planTask.getCaseType();
|
|
||||||
taskExecDto.setCaseType(type);
|
|
||||||
String scriptPath = planTask.getScriptJson();
|
|
||||||
|
|
||||||
Map<String, Object> caseParams = new HashMap<>();
|
|
||||||
if (taskParamsMap.containsKey(planTask.getId())) {
|
|
||||||
logger.debug("重试使用新数据");
|
|
||||||
caseParams = JSONUtil.toBean(taskParamsMap.get(planTask.getId()), Map.class);
|
|
||||||
} else {
|
|
||||||
if (StrUtil.isNotBlank(planTask.getCaseParam())) {
|
|
||||||
logger.debug("使用旧数据重试");
|
|
||||||
caseParams = JSONUtil.toBean(planTask.getCaseParam(), Map.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 更新静态数据与模糊数据为最新值
|
|
||||||
caseParams = this.handleQuoteData(caseParams, planTask.getEnvId(), planInfo.getProjectId());
|
|
||||||
planTask.setCaseParam(JSONUtil.toJsonStr(caseParams));
|
|
||||||
|
|
||||||
String appId = planTask.getAppId();
|
|
||||||
AtuSceneNodeExecDto sceneNodeExecDto = null;
|
|
||||||
|
|
||||||
//判断是否场景任务
|
|
||||||
if (PlanConstant.SCRIPT_TYPE_SCENE.equals(planTask.getCaseType())) {
|
|
||||||
// 调用脚本服务获取场景首节点信息,通知脚本服务场景重新发起
|
|
||||||
logger.debug("查询场景脚本的首节点信息");
|
|
||||||
SceneFirstNodeDto firstNodeDto = new SceneFirstNodeDto();
|
|
||||||
firstNodeDto.setTaskId(planTask.getId());
|
|
||||||
firstNodeDto.setCaseId(planTask.getCaseId());
|
|
||||||
String scriptId = planTask.getScriptId();
|
|
||||||
firstNodeDto.setScriptId(scriptId);
|
|
||||||
firstNodeDto.setParamMap(caseParams);
|
|
||||||
logger.debug("查询参数 => {}", JSONUtil.toJsonStr(firstNodeDto));
|
|
||||||
AtuSceneNodeInfoDto nodeInfo;
|
|
||||||
try {
|
|
||||||
ResultWrapper<AtuSceneNodeExecDto> firstNodeResult = publicFeignClient.getFirstNode(firstNodeDto);
|
|
||||||
if (firstNodeResult.isSuccess() && firstNodeResult.getData() != null) {
|
|
||||||
logger.debug("首节点信息为 => " + JSONUtil.toJsonStr(firstNodeResult));
|
|
||||||
sceneNodeExecDto = firstNodeResult.getData();
|
|
||||||
nodeInfo = sceneNodeExecDto.getNodeInfo();
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("获取场景脚本[ " + scriptId + "]首节点信息异常," + firstNodeResult.getMessage());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("获取场景首节点信息异常", e);
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.GET_SCENE_FIRST_NODE_FAIL);
|
|
||||||
}
|
|
||||||
if (ObjectUtil.isNull(nodeInfo)) {
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.SCENE_FIRST_NODE_INFO_IS_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
String sceneTaskId = IdUtil.simpleUUID();
|
|
||||||
taskExecDto.setTaskId(sceneTaskId);
|
|
||||||
scriptPath = nodeInfo.getScriptPath();
|
|
||||||
caseParams = nodeInfo.getCaseParam();
|
|
||||||
appId = queryAppId(taskExecDto.getPlanId(), nodeInfo.getPlatformType(),
|
|
||||||
nodeInfo.getAppPackage(), nodeInfo.getNodeType());
|
|
||||||
type = nodeInfo.getNodeType();
|
|
||||||
|
|
||||||
logger.debug("清理原节点任务");
|
|
||||||
AtuPlanSceneCaseTask deleteParams = new AtuPlanSceneCaseTask();
|
|
||||||
deleteParams.setTaskId(planTask.getId());
|
|
||||||
int rows = atuPlanSceneCaseTaskService.deleteByExample(deleteParams);
|
|
||||||
if (rows <= 0) {
|
|
||||||
logger.error("清理原场景节点任务失败");
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.CLEAR_SCENE_NODE_TASK_FAIL);
|
|
||||||
}
|
|
||||||
logger.debug("插入新节点任务");
|
|
||||||
AtuPlanSceneCaseTask planSceneCaseTask = new AtuPlanSceneCaseTask();
|
|
||||||
planSceneCaseTask.setId(sceneTaskId);
|
|
||||||
planSceneCaseTask.setTaskId(planTask.getId());
|
|
||||||
planSceneCaseTask.setScriptId(nodeInfo.getScriptId());
|
|
||||||
planSceneCaseTask.setVersionId(nodeInfo.getVersionId());
|
|
||||||
planSceneCaseTask.setVersionName(nodeInfo.getVersionName());
|
|
||||||
planSceneCaseTask.setScriptName(nodeInfo.getScriptName());
|
|
||||||
planSceneCaseTask.setScriptJson(nodeInfo.getScriptPath());
|
|
||||||
planSceneCaseTask.setNodeId(nodeInfo.getNodeId());
|
|
||||||
planSceneCaseTask.setNodeType(nodeInfo.getNodeType());
|
|
||||||
if (CollUtil.isNotEmpty(nodeInfo.getCaseParam())) {
|
|
||||||
planSceneCaseTask.setNodeParams(JSONUtil.toJsonStr(nodeInfo.getCaseParam()));
|
|
||||||
}
|
|
||||||
planSceneCaseTask.setCreatedTime(new Date());
|
|
||||||
planSceneCaseTask.setStatus(PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
|
||||||
planSceneCaseTask.setScriptJson(nodeInfo.getScriptPath());
|
|
||||||
atuPlanSceneCaseTaskService.insert(planSceneCaseTask);
|
|
||||||
|
|
||||||
}
|
|
||||||
taskExecDto.setScriptPath(scriptPath);
|
|
||||||
taskExecDto.setCaseParams(caseParams);
|
|
||||||
taskExecDto.setAppId(appId);
|
|
||||||
|
|
||||||
logger.debug("修改原任务状态");
|
|
||||||
planTask.setEngineId("");
|
|
||||||
planTask.setDeviceId("");
|
|
||||||
planTask.setAppId("");
|
|
||||||
planTask.setStatus(PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
|
||||||
planTask.setStartTime(null);
|
|
||||||
planTask.setEndTime(null);
|
|
||||||
planTask.setErrorMsg("");
|
|
||||||
planTask.setVideoUrl("");
|
|
||||||
planTask.setExecResultFile("");
|
|
||||||
planTask.setBugId("");
|
|
||||||
if (sceneNodeExecDto != null && sceneNodeExecDto.getSceneScriptUrl() != null) {
|
|
||||||
planTask.setScriptJson(sceneNodeExecDto.getSceneScriptUrl());
|
|
||||||
} else {
|
|
||||||
logger.info("首节点返回sceneScriptUrl为空" + sceneNodeExecDto);
|
|
||||||
}
|
|
||||||
int rows = atuPlanTaskService.updateByPrimaryKey(planTask);
|
|
||||||
if (rows <= 0) {
|
|
||||||
throw new PlatformRuntimeException(ExecPlanError.INIT_TASK_INFO_FAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("发送任务执行信息至消息队列");
|
|
||||||
sendToQueue(taskExecDto.getBatchId(), taskExecDto, type);
|
|
||||||
|
|
||||||
atuPlanInfoApiService.handleAutoType(PlanConstant.SCRIPT_TYPE_SCENE, caseTypeMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("计划批次重新发起委托");
|
|
||||||
atuPlanInfoApiService.handlePlanDevice(planInfo.getId(), planInfo.getPriority(), planBatch.getId(),
|
|
||||||
retryDto.getHasOfflineDevice(), caseTypeMap, true);
|
|
||||||
return true;
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(deletedFilePath)) {
|
||||||
|
AssociatedFilesDto associatedFilesDto = new AssociatedFilesDto();
|
||||||
|
associatedFilesDto.setObjId("-1");
|
||||||
|
associatedFilesDto.setFileIds(deletedFilePath);
|
||||||
|
attachmentFeignClient.associatedFiles(associatedFilesDto);
|
||||||
|
}
|
||||||
|
planBatchApiService.updateByEntity(planBatch);
|
||||||
|
atuPlanInfoApiService.updateStatusByLastBatchId(planBatch.getId(), planStatus);
|
||||||
|
|
||||||
|
logger.info("查询计划数据集中未被选择的意图数据");
|
||||||
|
Set<String> scriptIdSet = new HashSet<>();
|
||||||
|
Map<String, List<String>> envScriptMap = new HashMap<>();
|
||||||
|
Map<String, List<AtuPlanTask>> envScriptTaskMap = new HashMap<>();
|
||||||
|
List<String> taskIdList = new ArrayList<>();
|
||||||
|
for (AtuPlanTask planTask : planTaskList) {
|
||||||
|
taskIdList.add(planTask.getId());
|
||||||
|
scriptIdSet.add(planTask.getScriptId());
|
||||||
|
List<String> scriptIdList = new ArrayList<>();
|
||||||
|
if (envScriptMap.containsKey(planTask.getEnvId())) {
|
||||||
|
scriptIdList = envScriptMap.get(planTask.getEnvId());
|
||||||
|
}
|
||||||
|
scriptIdList.add(planTask.getScriptId());
|
||||||
|
envScriptMap.put(planTask.getEnvId(), scriptIdList);
|
||||||
|
String key = planTask.getEnvId() + "-" + planTask.getScriptId();
|
||||||
|
List<AtuPlanTask> envScriptTaskList = new ArrayList<>();
|
||||||
|
if (envScriptTaskMap.containsKey(key)) {
|
||||||
|
envScriptTaskList = envScriptTaskMap.get(key);
|
||||||
|
}
|
||||||
|
envScriptTaskList.add(planTask);
|
||||||
|
envScriptTaskMap.put(key, envScriptTaskList);
|
||||||
|
}
|
||||||
|
logger.debug("获取最新的输入项数据");
|
||||||
|
Map<String, String> taskParamsMap = getRetryTaskInputInfo(envScriptTaskMap, envScriptMap);
|
||||||
|
logger.debug("最新输入项数据大小:{}", taskParamsMap.size());
|
||||||
|
|
||||||
|
logger.debug("start 初始化批次缓存数据");
|
||||||
|
taskRetryInitCache(taskIdList, planBatch);
|
||||||
|
logger.debug("end 初始化批次缓存数据");
|
||||||
|
|
||||||
|
logger.debug("查询脚本最新数据");
|
||||||
|
logger.debug("脚本数量:{}", scriptIdSet.size());
|
||||||
|
Map<String, AtuScriptDetailDto> scriptMap = queryScriptDetailMap(scriptIdSet);
|
||||||
|
logger.debug("脚本最新信息数量:{}", scriptMap.size());
|
||||||
|
|
||||||
|
Map<String, Object> caseTypeMap = new HashMap<>();
|
||||||
|
caseTypeMap.put("hasPc", false);
|
||||||
|
caseTypeMap.put("hasMob", false);
|
||||||
|
caseTypeMap.put("hasInterface", false);
|
||||||
|
for (AtuPlanTask planTask : planTaskList) {
|
||||||
|
String status = planTask.getStatus();
|
||||||
|
logger.debug("原任务状态为: {}", status);
|
||||||
|
// 判断任务是否开始执行
|
||||||
|
if (PlanConstant.TASK_WAIT_EXECUTE_STATUS.equals(planTask.getStatus()) ||
|
||||||
|
PlanConstant.TASK_START_EXECUTE_STATUS.equals(planTask.getStatus())) {
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.TASK_NOT_FINISH);
|
||||||
|
}
|
||||||
|
logger.debug("修改任务脚本为最新脚本信息");
|
||||||
|
if (scriptMap.containsKey(planTask.getScriptId())) {
|
||||||
|
AtuScriptDetailDto atuScriptDetailDto = scriptMap.get(planTask.getScriptId());
|
||||||
|
planTask.setVersionId(atuScriptDetailDto.getVersionId());
|
||||||
|
planTask.setVersionName(atuScriptDetailDto.getVersionName());
|
||||||
|
planTask.setScriptName(atuScriptDetailDto.getScriptName());
|
||||||
|
planTask.setScriptJson(atuScriptDetailDto.getScriptPath());
|
||||||
|
planTask.setAppId(queryAppId(planInfo.getId(), atuScriptDetailDto.getPlatformType(),
|
||||||
|
atuScriptDetailDto.getAppPackage(), atuScriptDetailDto.getScriptType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("生成任务执行信息");
|
||||||
|
AtuTaskExecDto taskExecDto = new AtuTaskExecDto();
|
||||||
|
BeanUtil.copyProperties(planInfo, taskExecDto);
|
||||||
|
taskExecDto.setPlanId(planInfo.getId());
|
||||||
|
taskExecDto.setFailRetryNum(planInfo.getFailRetryCount());
|
||||||
|
taskExecDto.setBatchId(planTask.getBatchId());
|
||||||
|
taskExecDto.setTaskId(planTask.getId());
|
||||||
|
taskExecDto.setCaseId(planTask.getCaseId());
|
||||||
|
taskExecDto.setEnvId(planTask.getEnvId());
|
||||||
|
String type = planTask.getCaseType();
|
||||||
|
taskExecDto.setCaseType(type);
|
||||||
|
String scriptPath = planTask.getScriptJson();
|
||||||
|
|
||||||
|
Map<String, Object> caseParams = new HashMap<>();
|
||||||
|
if (taskParamsMap.containsKey(planTask.getId())) {
|
||||||
|
logger.debug("重试使用新数据");
|
||||||
|
caseParams = JSONUtil.toBean(taskParamsMap.get(planTask.getId()), Map.class);
|
||||||
|
} else {
|
||||||
|
if (StrUtil.isNotBlank(planTask.getCaseParam())) {
|
||||||
|
logger.debug("使用旧数据重试");
|
||||||
|
caseParams = JSONUtil.toBean(planTask.getCaseParam(), Map.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 更新静态数据与模糊数据为最新值
|
||||||
|
caseParams = this.handleQuoteData(caseParams, planTask.getEnvId(), planInfo.getProjectId());
|
||||||
|
planTask.setCaseParam(JSONUtil.toJsonStr(caseParams));
|
||||||
|
|
||||||
|
String appId = planTask.getAppId();
|
||||||
|
AtuSceneNodeExecDto sceneNodeExecDto = null;
|
||||||
|
|
||||||
|
//判断是否场景任务
|
||||||
|
if (PlanConstant.SCRIPT_TYPE_SCENE.equals(planTask.getCaseType())) {
|
||||||
|
// 调用脚本服务获取场景首节点信息,通知脚本服务场景重新发起
|
||||||
|
logger.debug("查询场景脚本的首节点信息");
|
||||||
|
SceneFirstNodeDto firstNodeDto = new SceneFirstNodeDto();
|
||||||
|
firstNodeDto.setTaskId(planTask.getId());
|
||||||
|
firstNodeDto.setCaseId(planTask.getCaseId());
|
||||||
|
String scriptId = planTask.getScriptId();
|
||||||
|
firstNodeDto.setScriptId(scriptId);
|
||||||
|
firstNodeDto.setParamMap(caseParams);
|
||||||
|
logger.debug("查询参数 => {}", JSONUtil.toJsonStr(firstNodeDto));
|
||||||
|
AtuSceneNodeInfoDto nodeInfo;
|
||||||
|
try {
|
||||||
|
ResultWrapper<AtuSceneNodeExecDto> firstNodeResult = publicFeignClient.getFirstNode(firstNodeDto);
|
||||||
|
if (firstNodeResult.isSuccess() && firstNodeResult.getData() != null) {
|
||||||
|
logger.debug("首节点信息为 => " + JSONUtil.toJsonStr(firstNodeResult));
|
||||||
|
sceneNodeExecDto = firstNodeResult.getData();
|
||||||
|
nodeInfo = sceneNodeExecDto.getNodeInfo();
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("获取场景脚本[ " + scriptId + "]首节点信息异常," + firstNodeResult.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("获取场景首节点信息异常", e);
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.GET_SCENE_FIRST_NODE_FAIL);
|
||||||
|
}
|
||||||
|
if (ObjectUtil.isNull(nodeInfo)) {
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.SCENE_FIRST_NODE_INFO_IS_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sceneTaskId = IdUtil.simpleUUID();
|
||||||
|
taskExecDto.setTaskId(sceneTaskId);
|
||||||
|
scriptPath = nodeInfo.getScriptPath();
|
||||||
|
caseParams = nodeInfo.getCaseParam();
|
||||||
|
appId = queryAppId(taskExecDto.getPlanId(), nodeInfo.getPlatformType(),
|
||||||
|
nodeInfo.getAppPackage(), nodeInfo.getNodeType());
|
||||||
|
type = nodeInfo.getNodeType();
|
||||||
|
|
||||||
|
logger.debug("清理原节点任务");
|
||||||
|
AtuPlanSceneCaseTask deleteParams = new AtuPlanSceneCaseTask();
|
||||||
|
deleteParams.setTaskId(planTask.getId());
|
||||||
|
int rows = atuPlanSceneCaseTaskService.deleteByExample(deleteParams);
|
||||||
|
if (rows <= 0) {
|
||||||
|
logger.error("清理原场景节点任务失败");
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.CLEAR_SCENE_NODE_TASK_FAIL);
|
||||||
|
}
|
||||||
|
logger.debug("插入新节点任务");
|
||||||
|
AtuPlanSceneCaseTask planSceneCaseTask = new AtuPlanSceneCaseTask();
|
||||||
|
planSceneCaseTask.setId(sceneTaskId);
|
||||||
|
planSceneCaseTask.setTaskId(planTask.getId());
|
||||||
|
planSceneCaseTask.setScriptId(nodeInfo.getScriptId());
|
||||||
|
planSceneCaseTask.setVersionId(nodeInfo.getVersionId());
|
||||||
|
planSceneCaseTask.setVersionName(nodeInfo.getVersionName());
|
||||||
|
planSceneCaseTask.setScriptName(nodeInfo.getScriptName());
|
||||||
|
planSceneCaseTask.setScriptJson(nodeInfo.getScriptPath());
|
||||||
|
planSceneCaseTask.setNodeId(nodeInfo.getNodeId());
|
||||||
|
planSceneCaseTask.setNodeType(nodeInfo.getNodeType());
|
||||||
|
if (CollUtil.isNotEmpty(nodeInfo.getCaseParam())) {
|
||||||
|
planSceneCaseTask.setNodeParams(JSONUtil.toJsonStr(nodeInfo.getCaseParam()));
|
||||||
|
}
|
||||||
|
planSceneCaseTask.setCreatedTime(new Date());
|
||||||
|
planSceneCaseTask.setStatus(PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
||||||
|
planSceneCaseTask.setScriptJson(nodeInfo.getScriptPath());
|
||||||
|
atuPlanSceneCaseTaskService.insert(planSceneCaseTask);
|
||||||
|
|
||||||
|
}
|
||||||
|
taskExecDto.setScriptPath(scriptPath);
|
||||||
|
taskExecDto.setCaseParams(caseParams);
|
||||||
|
taskExecDto.setAppId(appId);
|
||||||
|
|
||||||
|
logger.debug("修改原任务状态");
|
||||||
|
planTask.setEngineId("");
|
||||||
|
planTask.setDeviceId("");
|
||||||
|
planTask.setAppId("");
|
||||||
|
planTask.setStatus(PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
||||||
|
planTask.setStartTime(null);
|
||||||
|
planTask.setEndTime(null);
|
||||||
|
planTask.setErrorMsg("");
|
||||||
|
planTask.setVideoUrl("");
|
||||||
|
planTask.setExecResultFile("");
|
||||||
|
planTask.setBugId("");
|
||||||
|
if (sceneNodeExecDto != null && sceneNodeExecDto.getSceneScriptUrl() != null) {
|
||||||
|
planTask.setScriptJson(sceneNodeExecDto.getSceneScriptUrl());
|
||||||
|
} else {
|
||||||
|
logger.info("首节点返回sceneScriptUrl为空" + sceneNodeExecDto);
|
||||||
|
}
|
||||||
|
int rows = atuPlanTaskService.updateByPrimaryKey(planTask);
|
||||||
|
if (rows <= 0) {
|
||||||
|
throw new PlatformRuntimeException(ExecPlanError.INIT_TASK_INFO_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("发送任务执行信息至消息队列");
|
||||||
|
sendToQueue(taskExecDto.getBatchId(), taskExecDto, type);
|
||||||
|
|
||||||
|
atuPlanInfoApiService.handleAutoType(PlanConstant.SCRIPT_TYPE_SCENE, caseTypeMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("计划批次重新发起委托");
|
||||||
|
atuPlanInfoApiService.handlePlanDevice(planInfo.getId(), planInfo.getPriority(), planBatch.getId(),
|
||||||
|
retryDto.getHasOfflineDevice(), caseTypeMap, true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -88,7 +88,7 @@ public enum ExecPlanError implements PlatformError {
|
||||||
|
|
||||||
GET_FILE_FAIL("获取文件失败"),
|
GET_FILE_FAIL("获取文件失败"),
|
||||||
EMPTY_BATCH_ID("批次id不能为空"),
|
EMPTY_BATCH_ID("批次id不能为空"),
|
||||||
BATCH_IS_DEALING_WITH_RETRY("批次的任务重试正在处理中..."),
|
BATCH_IS_DEALING_WITH_RETRY("批次信息正在处理中,请稍后尝试操作..."),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误码结束值
|
* 错误码结束值
|
||||||
|
|
|
@ -9,6 +9,7 @@ import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import net.northking.cctp.common.enums.FileBusinessTypeEnum;
|
import net.northking.cctp.common.enums.FileBusinessTypeEnum;
|
||||||
|
import net.northking.cctp.common.exception.PlatformRuntimeException;
|
||||||
import net.northking.cctp.common.s3.NKFile;
|
import net.northking.cctp.common.s3.NKFile;
|
||||||
import net.northking.cctp.common.s3.SimpleStorageService;
|
import net.northking.cctp.common.s3.SimpleStorageService;
|
||||||
import net.northking.cctp.common.security.authentication.NKSecurityContext;
|
import net.northking.cctp.common.security.authentication.NKSecurityContext;
|
||||||
|
@ -27,6 +28,7 @@ import net.northking.cctp.executePlan.dto.planBatch.*;
|
||||||
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanRunDto;
|
import net.northking.cctp.executePlan.dto.planInfo.AtuPlanRunDto;
|
||||||
import net.northking.cctp.executePlan.dto.planTask.ScriptStatusStatistic;
|
import net.northking.cctp.executePlan.dto.planTask.ScriptStatusStatistic;
|
||||||
import net.northking.cctp.executePlan.enums.MobilePlatformEnum;
|
import net.northking.cctp.executePlan.enums.MobilePlatformEnum;
|
||||||
|
import net.northking.cctp.executePlan.exception.ExecPlanError;
|
||||||
import net.northking.cctp.executePlan.feign.PublicFeignClient;
|
import net.northking.cctp.executePlan.feign.PublicFeignClient;
|
||||||
import net.northking.cctp.executePlan.utils.MinioPathUtils;
|
import net.northking.cctp.executePlan.utils.MinioPathUtils;
|
||||||
import org.redisson.api.RLock;
|
import org.redisson.api.RLock;
|
||||||
|
@ -34,6 +36,7 @@ import org.redisson.api.RedissonClient;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.amqp.core.AmqpAdmin;
|
import org.springframework.amqp.core.AmqpAdmin;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
@ -119,6 +122,9 @@ public class PlanBatchTaskDataUpdateJob {
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisLockRegistry redisLockRegistry;
|
private RedisLockRegistry redisLockRegistry;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
private final static String LOCK_KEY_BATCH_SUM = "LOCK:PLAN:BATCH-SUM-DATA-UPDATE-METHOD";
|
private final static String LOCK_KEY_BATCH_SUM = "LOCK:PLAN:BATCH-SUM-DATA-UPDATE-METHOD";
|
||||||
|
|
||||||
private final static String BATCH_IS_NULL_COUNT_HASH = "PLAN:BATCH:NULL-COUNT-HASH";
|
private final static String BATCH_IS_NULL_COUNT_HASH = "PLAN:BATCH:NULL-COUNT-HASH";
|
||||||
|
@ -165,175 +171,185 @@ public class PlanBatchTaskDataUpdateJob {
|
||||||
String batchId = key.substring(key.lastIndexOf(":") + 1);
|
String batchId = key.substring(key.lastIndexOf(":") + 1);
|
||||||
String clusterKeyPrefix = RedisConstant.CLUSTER_KEY_PREFIX + batchId.substring(0, 4) +
|
String clusterKeyPrefix = RedisConstant.CLUSTER_KEY_PREFIX + batchId.substring(0, 4) +
|
||||||
RedisConstant.CLUSTER_KEY_SUFFIX;
|
RedisConstant.CLUSTER_KEY_SUFFIX;
|
||||||
|
Lock batchLock = redisLockRegistry.obtain(String.format("%s%s", RedisConstant.PLAN_BATCH_RETRY_LOCK_PRE, batchId));
|
||||||
// 通过数据库进行统计,减少统计数据出错的原因
|
if (!batchLock.tryLock()) {
|
||||||
AtuPlanBatch batch = this.planBatchService.findByPrimaryKey(batchId);
|
// 获取不到锁,正在处理重试,此次统计不需要
|
||||||
if (batch == null) {
|
logger.info("批次【{}】正在处理任务重试操作,此次统计不需要", batchId);
|
||||||
logger.info("批次【{}】信息目前不存在,再等待下一次查询...", batchId);
|
|
||||||
Boolean existFlag = redisTemplate.opsForHash().hasKey(BATCH_IS_NULL_COUNT_HASH, batchId);
|
|
||||||
if (existFlag) {
|
|
||||||
Object nullCount = redisTemplate.opsForHash().get(BATCH_IS_NULL_COUNT_HASH, batchId);
|
|
||||||
if (nullCount != null && NumberUtil.isNumber(nullCount.toString())) {
|
|
||||||
int i = Integer.parseInt(nullCount.toString());
|
|
||||||
if (i < 100) { // 统计100次后依然没有批次信息,批次不存在
|
|
||||||
redisTemplate.opsForHash().put(BATCH_IS_NULL_COUNT_HASH, batchId, i + 1);
|
|
||||||
} else {
|
|
||||||
// 没有对应批次数据,删除缓存数据
|
|
||||||
logger.debug("没有对应的批次信息[{}],删除缓存数据", batchId);
|
|
||||||
redisTemplate.delete(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
redisTemplate.opsForHash().put(BATCH_IS_NULL_COUNT_HASH, batchId, 1);
|
|
||||||
}
|
|
||||||
return; // 退出这个批次统计
|
|
||||||
}
|
|
||||||
// 批次信息存在
|
|
||||||
AtuPlanTask totalQ = new AtuPlanTask();
|
|
||||||
totalQ.setBatchId(batchId);
|
|
||||||
long currentTaskTotal = planTaskService.count(totalQ);
|
|
||||||
// 判断批次任务是否已经全部生成
|
|
||||||
if (batch.getTaskTotal() > currentTaskTotal) {
|
|
||||||
logger.info("批次[{}]正在生成任务中,结束统计...", batchId);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 以脚本维度统计批次下各脚本的执行情况
|
try {
|
||||||
AtuPlanTask taskQ = new AtuPlanTask();
|
// 通过数据库进行统计,减少统计数据出错的原因
|
||||||
taskQ.setBatchId(batchId);
|
AtuPlanBatch batch = this.planBatchService.findByPrimaryKey(batchId);
|
||||||
List<ScriptStatusStatistic> resultList = planTaskService.countTaskStatus(taskQ);
|
if (batch == null) {
|
||||||
List<String> batchStatusList = new ArrayList<>();
|
logger.info("批次【{}】信息目前不存在,再等待下一次查询...", batchId);
|
||||||
for (ScriptStatusStatistic result : resultList) {
|
Boolean existFlag = redisTemplate.opsForHash().hasKey(BATCH_IS_NULL_COUNT_HASH, batchId);
|
||||||
Set<String> statusSet = result.getStatusSet();
|
if (existFlag) {
|
||||||
result.setStatus(scriptStatus(statusSet)); // 根据脚本下的所有任务确定脚本的执行结果
|
Object nullCount = redisTemplate.opsForHash().get(BATCH_IS_NULL_COUNT_HASH, batchId);
|
||||||
batchStatusList.add(result.getStatus());
|
if (nullCount != null && NumberUtil.isNumber(nullCount.toString())) {
|
||||||
}
|
int i = Integer.parseInt(nullCount.toString());
|
||||||
int allScriptCount = batchStatusList.size(); // 总脚本执行数
|
if (i < 100) { // 统计100次后依然没有批次信息,批次不存在
|
||||||
// 等待中
|
redisTemplate.opsForHash().put(BATCH_IS_NULL_COUNT_HASH, batchId, i + 1);
|
||||||
int waitCount = Collections.frequency(batchStatusList, PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
} else {
|
||||||
// 执行中
|
// 没有对应批次数据,删除缓存数据
|
||||||
int ingCount = Collections.frequency(batchStatusList, PlanConstant.TASK_START_EXECUTE_STATUS);
|
logger.debug("没有对应的批次信息[{}],删除缓存数据", batchId);
|
||||||
// 成功
|
redisTemplate.delete(key);
|
||||||
int successCount = Collections.frequency(batchStatusList, PlanConstant.TASK_EXECUTE_SUCCESS_STATUS);
|
}
|
||||||
// 执行失败
|
}
|
||||||
int executeFailCount = Collections.frequency(batchStatusList, PlanConstant.TASK_EXECUTE_FAIL_STATUS);
|
|
||||||
// 断言失败
|
|
||||||
int assertFailCount = Collections.frequency(batchStatusList, PlanConstant.TASK_ASSERT_FAIL_STATUS);
|
|
||||||
// 取消的
|
|
||||||
int cancelCount = Collections.frequency(batchStatusList, PlanConstant.TASK_CANCEL_STATUS);
|
|
||||||
// 超时的
|
|
||||||
int timeoutCount = Collections.frequency(batchStatusList, PlanConstant.TASK_TIMEOUT_STATUS);
|
|
||||||
|
|
||||||
if (waitCount > 0 || ingCount > 0) { // 批次还没有完成
|
|
||||||
// 检查批次的开始时间
|
|
||||||
Date createdTime = batch.getCreatedTime();
|
|
||||||
if (createdTime != null) { // 有创建时间,那么比较开始时间与现在的时间差
|
|
||||||
LocalDateTime createDateTime = createdTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
Duration duration = Duration.between(createDateTime, now);
|
|
||||||
long hours = duration.toHours();
|
|
||||||
if (atuPlanConfig.isBatchExecuteTimeoutEnabled() && hours > atuPlanConfig.getBatchExecuteTimeout().longValue()) { // 参数化
|
|
||||||
logger.info("批次[{}-{}]已创建{}小时,任务没有执行完成,强制结束批次", batch.getId(), batch.getBatch(), 48);
|
|
||||||
// 如果批次的创建时间离现在已经过去48小时还没完成,那么判定批次已完成,等待中|执行中 的任务全部算超时处理
|
|
||||||
timeoutCount += waitCount;
|
|
||||||
timeoutCount += ingCount;
|
|
||||||
waitCount = 0;
|
|
||||||
ingCount = 0;
|
|
||||||
// 更新批次下 等待中(0)|执行中(1) 的任务全部算超时处理(6)
|
|
||||||
this.planTaskService.batchUpdateTaskStatusToTimeout(batch.getId(), PlanConstant.TASK_TIMEOUT_STATUS, PlanConstant.TASK_WAIT_EXECUTE_STATUS, PlanConstant.TASK_START_EXECUTE_STATUS);
|
|
||||||
} else {
|
} else {
|
||||||
// 批次还没有完成,退出统计
|
redisTemplate.opsForHash().put(BATCH_IS_NULL_COUNT_HASH, batchId, 1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
return; // 退出这个批次统计
|
||||||
// 有批次信息,但是没有创建时间,应该是数据有问题
|
}
|
||||||
logger.debug("批次[{}]没有创建时间", batch.getId());
|
// 批次信息存在
|
||||||
|
AtuPlanTask totalQ = new AtuPlanTask();
|
||||||
|
totalQ.setBatchId(batchId);
|
||||||
|
long currentTaskTotal = planTaskService.count(totalQ);
|
||||||
|
// 判断批次任务是否已经全部生成
|
||||||
|
if (batch.getTaskTotal() > currentTaskTotal) {
|
||||||
|
logger.info("批次[{}]正在生成任务中,结束统计...", batchId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
// 以脚本维度统计批次下各脚本的执行情况
|
||||||
// 批次已完成
|
AtuPlanTask taskQ = new AtuPlanTask();
|
||||||
|
taskQ.setBatchId(batchId);
|
||||||
// 更新批次表
|
List<ScriptStatusStatistic> resultList = planTaskService.countTaskStatus(taskQ);
|
||||||
AtuPlanBatch planBatch = new AtuPlanBatch();
|
List<String> batchStatusList = new ArrayList<>();
|
||||||
planBatch.setId(batchId);
|
for (ScriptStatusStatistic result : resultList) {
|
||||||
planBatch.setSuccessNum(successCount);
|
Set<String> statusSet = result.getStatusSet();
|
||||||
planBatch.setExecFailNum(executeFailCount);
|
result.setStatus(scriptStatus(statusSet)); // 根据脚本下的所有任务确定脚本的执行结果
|
||||||
planBatch.setAssertFailNum(assertFailCount);
|
batchStatusList.add(result.getStatus());
|
||||||
planBatch.setTimeoutNum(timeoutCount);
|
|
||||||
planBatch.setCancelNum(cancelCount);
|
|
||||||
|
|
||||||
planBatch.setSuccessRate(MsgConstant.PLAN_BATCH_SUCCESS_RATE);
|
|
||||||
if (planBatch.getSuccessNum() > 0 && allScriptCount > 0) {
|
|
||||||
planBatch.setSuccessRate(NumberUtil.decimalFormat(MsgConstant.PATTERN_HASH_DOT_HASH_HASH, NumberUtil.div(planBatch.getSuccessNum().intValue(), allScriptCount)));
|
|
||||||
}
|
|
||||||
// 查询批次最先开始执行的任务的开始时间
|
|
||||||
if (planBatch.getStartTime() == null) {
|
|
||||||
Long firstTaskStartTime = planTaskService.queryBatchFirstTaskStartTime(batchId);
|
|
||||||
if (ObjectUtil.isNotNull(firstTaskStartTime)) {
|
|
||||||
planBatch.setStartTime(new Date(firstTaskStartTime));
|
|
||||||
}
|
}
|
||||||
}
|
int allScriptCount = batchStatusList.size(); // 总脚本执行数
|
||||||
// 任务状态判断
|
// 等待中
|
||||||
String planStatus = "";
|
int waitCount = Collections.frequency(batchStatusList, PlanConstant.TASK_WAIT_EXECUTE_STATUS);
|
||||||
if (planBatch.getCancelNum() > 0) {
|
// 执行中
|
||||||
planStatus = PlanConstant.PLAN_CANCEL_STATUS;
|
int ingCount = Collections.frequency(batchStatusList, PlanConstant.TASK_START_EXECUTE_STATUS);
|
||||||
// 修改为取消状态
|
// 成功
|
||||||
planBatch.setStatus(PlanConstant.BATCH_CANCEL_STATUS);
|
int successCount = Collections.frequency(batchStatusList, PlanConstant.TASK_EXECUTE_SUCCESS_STATUS);
|
||||||
} else {
|
// 执行失败
|
||||||
planStatus = PlanConstant.PLAN_FINISH_STATUS;
|
int executeFailCount = Collections.frequency(batchStatusList, PlanConstant.TASK_EXECUTE_FAIL_STATUS);
|
||||||
// 修改为已完成状态
|
// 断言失败
|
||||||
planBatch.setStatus(PlanConstant.BATCH_FINISH_STATUS);
|
int assertFailCount = Collections.frequency(batchStatusList, PlanConstant.TASK_ASSERT_FAIL_STATUS);
|
||||||
|
// 取消的
|
||||||
|
int cancelCount = Collections.frequency(batchStatusList, PlanConstant.TASK_CANCEL_STATUS);
|
||||||
|
// 超时的
|
||||||
|
int timeoutCount = Collections.frequency(batchStatusList, PlanConstant.TASK_TIMEOUT_STATUS);
|
||||||
|
|
||||||
|
if (waitCount > 0 || ingCount > 0) { // 批次还没有完成
|
||||||
|
// 检查批次的开始时间
|
||||||
|
Date createdTime = batch.getCreatedTime();
|
||||||
|
if (createdTime != null) { // 有创建时间,那么比较开始时间与现在的时间差
|
||||||
|
LocalDateTime createDateTime = createdTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(createDateTime, now);
|
||||||
|
long hours = duration.toHours();
|
||||||
|
if (atuPlanConfig.isBatchExecuteTimeoutEnabled() && hours > atuPlanConfig.getBatchExecuteTimeout().longValue()) { // 参数化
|
||||||
|
logger.info("批次[{}-{}]已创建{}小时,任务没有执行完成,强制结束批次", batch.getId(), batch.getBatch(), 48);
|
||||||
|
// 如果批次的创建时间离现在已经过去48小时还没完成,那么判定批次已完成,等待中|执行中 的任务全部算超时处理
|
||||||
|
timeoutCount += waitCount;
|
||||||
|
timeoutCount += ingCount;
|
||||||
|
waitCount = 0;
|
||||||
|
ingCount = 0;
|
||||||
|
// 更新批次下 等待中(0)|执行中(1) 的任务全部算超时处理(6)
|
||||||
|
this.planTaskService.batchUpdateTaskStatusToTimeout(batch.getId(), PlanConstant.TASK_TIMEOUT_STATUS, PlanConstant.TASK_WAIT_EXECUTE_STATUS, PlanConstant.TASK_START_EXECUTE_STATUS);
|
||||||
|
} else {
|
||||||
|
// 批次还没有完成,退出统计
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 有批次信息,但是没有创建时间,应该是数据有问题
|
||||||
|
logger.debug("批次[{}]没有创建时间", batch.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 批次已完成
|
||||||
|
|
||||||
|
// 更新批次表
|
||||||
|
AtuPlanBatch planBatch = new AtuPlanBatch();
|
||||||
|
planBatch.setId(batchId);
|
||||||
|
planBatch.setSuccessNum(successCount);
|
||||||
|
planBatch.setExecFailNum(executeFailCount);
|
||||||
|
planBatch.setAssertFailNum(assertFailCount);
|
||||||
|
planBatch.setTimeoutNum(timeoutCount);
|
||||||
|
planBatch.setCancelNum(cancelCount);
|
||||||
|
|
||||||
|
planBatch.setSuccessRate(MsgConstant.PLAN_BATCH_SUCCESS_RATE);
|
||||||
|
if (planBatch.getSuccessNum() > 0 && allScriptCount > 0) {
|
||||||
|
planBatch.setSuccessRate(NumberUtil.decimalFormat(MsgConstant.PATTERN_HASH_DOT_HASH_HASH, NumberUtil.div(planBatch.getSuccessNum().intValue(), allScriptCount)));
|
||||||
|
}
|
||||||
|
// 查询批次最先开始执行的任务的开始时间
|
||||||
|
if (planBatch.getStartTime() == null) {
|
||||||
|
Long firstTaskStartTime = planTaskService.queryBatchFirstTaskStartTime(batchId);
|
||||||
|
if (ObjectUtil.isNotNull(firstTaskStartTime)) {
|
||||||
|
planBatch.setStartTime(new Date(firstTaskStartTime));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 任务状态判断
|
||||||
|
String planStatus = "";
|
||||||
|
if (planBatch.getCancelNum() > 0) {
|
||||||
|
planStatus = PlanConstant.PLAN_CANCEL_STATUS;
|
||||||
|
// 修改为取消状态
|
||||||
|
planBatch.setStatus(PlanConstant.BATCH_CANCEL_STATUS);
|
||||||
|
} else {
|
||||||
|
planStatus = PlanConstant.PLAN_FINISH_STATUS;
|
||||||
|
// 修改为已完成状态
|
||||||
|
planBatch.setStatus(PlanConstant.BATCH_FINISH_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询批次最后执行完成的任务的结束时间
|
||||||
|
Long lastTaskEndTime = planTaskService.queryBatchLastTaskEndTime(batchId);
|
||||||
|
if (ObjectUtil.isNotNull(lastTaskEndTime)) {
|
||||||
|
planBatch.setEndTime(new Date(lastTaskEndTime));
|
||||||
|
}
|
||||||
|
logger.debug("更新批次信息");
|
||||||
|
planBatchService.updateByPrimaryKey(planBatch);
|
||||||
|
|
||||||
|
// 删除任务队列
|
||||||
|
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_PC_KEY + batchId);
|
||||||
|
// 移动端删除各个平台对于的队列
|
||||||
|
MobilePlatformEnum[] platformEnums = MobilePlatformEnum.values();
|
||||||
|
for (MobilePlatformEnum platformEnum : platformEnums) {
|
||||||
|
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_MOB_KEY + platformEnum.getName() + "." + batchId);
|
||||||
|
}
|
||||||
|
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_API_KEY + batchId);
|
||||||
|
|
||||||
|
//获取更新后的批次信息
|
||||||
|
AtuPlanBatchDetailDto atuPlanBatchDetailDto = planBatchService.queryBatchDetailById(planBatch.getId());
|
||||||
|
|
||||||
|
// 判断是否计划最后一批次
|
||||||
|
AtuPlanInfo planInfo = planInfoService.queryByLastBatchId(batchId);
|
||||||
|
if (ObjectUtil.isNotNull(planInfo)) {
|
||||||
|
// 是则更新计划表
|
||||||
|
planInfo.setStatus(planStatus);
|
||||||
|
planInfo.setWaitingNum(waitCount);
|
||||||
|
planInfo.setRunningNum(ingCount);
|
||||||
|
planInfo.setSuccessNum(planBatch.getSuccessNum());
|
||||||
|
planInfo.setExecFailNum(planBatch.getExecFailNum());
|
||||||
|
planInfo.setAssertFailNum(planBatch.getAssertFailNum());
|
||||||
|
planInfo.setTimeoutNum(planBatch.getTimeoutNum());
|
||||||
|
planInfo.setCancelNum(planBatch.getCancelNum());
|
||||||
|
//不用代码生成的方法
|
||||||
|
planInfoService.updatePlanResultById(planInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.execute(() -> {
|
||||||
|
// 保存设备性能数据
|
||||||
|
saveDevicePerData(atuPlanBatchDetailDto);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2.2. 删除缓存中已完成批次的记录
|
||||||
|
logger.debug("删除批次统计缓存 => " + key);
|
||||||
|
redisTemplate.delete(key);
|
||||||
|
|
||||||
|
// 收尾处理
|
||||||
|
AtuPlanInfo batchPlanInfo = planInfoService.findByBatchId(batchId);
|
||||||
|
if (batchPlanInfo != null) {
|
||||||
|
handleEnd(batchPlanInfo, atuPlanBatchDetailDto);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
batchLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询批次最后执行完成的任务的结束时间
|
|
||||||
Long lastTaskEndTime = planTaskService.queryBatchLastTaskEndTime(batchId);
|
|
||||||
if (ObjectUtil.isNotNull(lastTaskEndTime)) {
|
|
||||||
planBatch.setEndTime(new Date(lastTaskEndTime));
|
|
||||||
}
|
|
||||||
logger.debug("更新批次信息");
|
|
||||||
planBatchService.updateByPrimaryKey(planBatch);
|
|
||||||
|
|
||||||
// 删除任务队列
|
|
||||||
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_PC_KEY + batchId);
|
|
||||||
// 移动端删除各个平台对于的队列
|
|
||||||
MobilePlatformEnum[] platformEnums = MobilePlatformEnum.values();
|
|
||||||
for (MobilePlatformEnum platformEnum : platformEnums) {
|
|
||||||
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_MOB_KEY + platformEnum.getName() + "." + batchId);
|
|
||||||
}
|
|
||||||
amqpAdmin.deleteQueue(RabbitConstant.TASK_EXEC_QUEUE_API_KEY + batchId);
|
|
||||||
|
|
||||||
//获取更新后的批次信息
|
|
||||||
AtuPlanBatchDetailDto atuPlanBatchDetailDto = planBatchService.queryBatchDetailById(planBatch.getId());
|
|
||||||
|
|
||||||
// 判断是否计划最后一批次
|
|
||||||
AtuPlanInfo planInfo = planInfoService.queryByLastBatchId(batchId);
|
|
||||||
if (ObjectUtil.isNotNull(planInfo)) {
|
|
||||||
// 是则更新计划表
|
|
||||||
planInfo.setStatus(planStatus);
|
|
||||||
planInfo.setWaitingNum(waitCount);
|
|
||||||
planInfo.setRunningNum(ingCount);
|
|
||||||
planInfo.setSuccessNum(planBatch.getSuccessNum());
|
|
||||||
planInfo.setExecFailNum(planBatch.getExecFailNum());
|
|
||||||
planInfo.setAssertFailNum(planBatch.getAssertFailNum());
|
|
||||||
planInfo.setTimeoutNum(planBatch.getTimeoutNum());
|
|
||||||
planInfo.setCancelNum(planBatch.getCancelNum());
|
|
||||||
//不用代码生成的方法
|
|
||||||
planInfoService.updatePlanResultById(planInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
executor.execute(() -> {
|
|
||||||
// 保存设备性能数据
|
|
||||||
saveDevicePerData(atuPlanBatchDetailDto);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2.2. 删除缓存中已完成批次的记录
|
|
||||||
logger.debug("删除批次统计缓存 => " + key);
|
|
||||||
redisTemplate.delete(key);
|
|
||||||
|
|
||||||
// 收尾处理
|
|
||||||
AtuPlanInfo batchPlanInfo = planInfoService.findByBatchId(batchId);
|
|
||||||
if (batchPlanInfo != null) {
|
|
||||||
handleEnd(batchPlanInfo, atuPlanBatchDetailDto);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
logger.debug("同步缓存中计划批次统计数据----end----");
|
logger.debug("同步缓存中计划批次统计数据----end----");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
Loading…
Reference in New Issue