fix:修复多线程导致无法锁定同排站点

This commit is contained in:
2026-05-01 17:00:37 +08:00
parent a0834a4ee7
commit 8a7cd4332c
8 changed files with 459 additions and 324 deletions

View File

@@ -3,16 +3,14 @@ package org.nl.system.service.quartz.task;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.collections4.CollectionUtils;
import org.nl.acs.common.base.CommonFinalParam;
import org.nl.acs.instruction.domain.Instruction; import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.enums.InstructionStatusEnum; import org.nl.acs.instruction.enums.InstructionStatusEnum;
import org.nl.acs.instruction.service.InstructionService; import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.opc.DeviceAppService; import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl; import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.route.service.dto.RouteLineDto;
import org.nl.acs.task.enums.TaskStatusEnum; import org.nl.acs.task.enums.TaskStatusEnum;
import org.nl.acs.task.enums.TaskTypeEnum; import org.nl.acs.task.enums.TaskTypeEnum;
import org.nl.acs.task.service.TaskService; import org.nl.acs.task.service.TaskService;
@@ -22,11 +20,15 @@ import org.nl.config.SpringContextHolder;
import org.nl.system.service.lucene.LuceneExecuteLogService; import org.nl.system.service.lucene.LuceneExecuteLogService;
import org.nl.system.service.lucene.dto.LuceneLogDto; import org.nl.system.service.lucene.dto.LuceneLogDto;
import org.nl.system.service.lucene.impl.LuceneExecuteLogServiceImpl; import org.nl.system.service.lucene.impl.LuceneExecuteLogServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -34,252 +36,392 @@ import java.util.stream.Collectors;
*/ */
@Slf4j @Slf4j
@Component @Component
@RequiredArgsConstructor
public class AutoCreateInst { public class AutoCreateInst {
private final RedissonClient redissonClient;
/** /**
* 根据任务状态创建指令、生成下一条指令 * 根据任务状态创建指令、生成下一条指令
* 创建指令前需要判断是否条件具备:起始位置是否有货、目标位置是否有货 * 创建指令前需要判断是否条件具备:起始位置是否有货、目标位置是否有货
*/ */
public void run() throws Exception { // public void run() throws Exception {
log.info("自动生成指令" + DateUtil.now()); // log.info("自动生成指令" + DateUtil.now());
TaskService taskserver = SpringContextHolder.getBean(TaskService.class); // TaskService taskserver = SpringContextHolder.getBean(TaskService.class);
InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); // InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class);
RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class); // RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class);
DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); // DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
LuceneExecuteLogService luceneExecuteLogService = SpringContextHolder.getBean(LuceneExecuteLogServiceImpl.class); // LuceneExecuteLogService luceneExecuteLogService = SpringContextHolder.getBean(LuceneExecuteLogServiceImpl.class);
List<TaskDto> list = taskserver.queryAllByStatus("0"); // List<TaskDto> list = taskserver.queryAllByStatus("0");
for (int i = 0; i < list.size(); i++) { // for (int i = 0; i < list.size(); i++) {
TaskDto acsTask = list.get(i); // TaskDto acsTask = list.get(i);
if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.AGV_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) { // if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.AGV_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) {
continue; // continue;
} // }
if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.Truss_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) { // if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.Truss_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) {
continue; // continue;
} // }
Boolean flag=false; // Boolean flag=false;
String taskid = acsTask.getTask_id(); // String taskid = acsTask.getTask_id();
String taskcode = acsTask.getTask_code(); // String taskcode = acsTask.getTask_code();
String task_type = acsTask.getTask_type(); // String task_type = acsTask.getTask_type();
String vehiclecode = acsTask.getVehicle_code(); // String vehiclecode = acsTask.getVehicle_code();
String priority = acsTask.getPriority(); // String priority = acsTask.getPriority();
String is_send = acsTask.getIs_send(); // String is_send = acsTask.getIs_send();
//
String start_device_code = acsTask.getStart_device_code(); // String start_device_code = acsTask.getStart_device_code();
String start_point=null; // String start_point=null;
if(start_device_code.contains("BCPRK")){ // if(start_device_code.contains("BCPRK")){
String[] parts = start_device_code.split("-", 2); // String[] parts = start_device_code.split("-", 2);
start_point=parts[0]; // start_point=parts[0];
}else if(start_device_code.contains("CPRK")){ // }else if(start_device_code.contains("CPRK")){
String[] parts = start_device_code.split("-", 2); // String[] parts = start_device_code.split("-", 2);
start_point=parts[0]; // start_point=parts[0];
} // }
if(start_point != null) { // if(start_point != null) {
if (start_point.equals("CPRK1")) { // if (start_point.equals("CPRK1")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("CPRK1")) { // if (start_point.equals("CPRK1")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("CPRK2")) { // } else if (start_point.equals("CPRK2")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("CPRK2")) { // if (start_point.equals("CPRK2")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("CPRK3")) { // } else if (start_point.equals("CPRK3")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("CPRK3")) { // if (start_point.equals("CPRK3")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("CPRK4")) { // } else if (start_point.equals("CPRK4")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("CPRK4")) { // if (start_point.equals("CPRK4")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("CPRK5")) { // } else if (start_point.equals("CPRK5")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("CPRK5")) { // if (start_point.equals("CPRK5")) {
flag = true; // flag = true;
} // }
} // }
}else if (start_point.equals("BCPRK1")) { // }else if (start_point.equals("BCPRK1")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("BCPRK1")) { // if (start_point.equals("BCPRK1")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("BCPRK2")) { // } else if (start_point.equals("BCPRK2")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("BCPRK2")) { // if (start_point.equals("BCPRK2")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("BCPRK3")) { // } else if (start_point.equals("BCPRK3")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("BCPRK3")) { // if (start_point.equals("BCPRK3")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("BCPRK4")) { // } else if (start_point.equals("BCPRK4")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("BCPRK4")) { // if (start_point.equals("BCPRK4")) {
flag = true; // flag = true;
} // }
} // }
} else if (start_point.equals("BCPRK5")) { // } else if (start_point.equals("BCPRK5")) {
List<TaskDto> list1 = taskserver.queryAllByStatus("1"); // List<TaskDto> list1 = taskserver.queryAllByStatus("1");
for (int j = 0; j < list1.size(); j++) { // for (int j = 0; j < list1.size(); j++) {
String start_device_code1 = list1.get(j).getStart_device_code(); // String start_device_code1 = list1.get(j).getStart_device_code();
String[] parts = start_device_code1.split("-", 2); // String[] parts = start_device_code1.split("-", 2);
start_point = parts[0]; // start_point = parts[0];
if (start_point.equals("BCPRK5")) { // if (start_point.equals("BCPRK5")) {
flag = true; // flag = true;
} // }
} // }
} // }
} // }
if (flag){ // if (flag){
continue; // continue;
} // }
String start_point_code = acsTask.getStart_point_code(); // String start_point_code = acsTask.getStart_point_code();
//
String put_device_code = acsTask.getPut_device_code(); // String put_device_code = acsTask.getPut_device_code();
String put_point_code = acsTask.getPut_point_code(); // String put_point_code = acsTask.getPut_point_code();
//
String next_device_code = acsTask.getNext_device_code(); // String next_device_code = acsTask.getNext_device_code();
String next_point_code = acsTask.getNext_point_code(); // String next_point_code = acsTask.getNext_point_code();
//
String route_plan_code = acsTask.getRoute_plan_code(); // String route_plan_code = acsTask.getRoute_plan_code();
String vehicleType = acsTask.getVehicle_type(); // String vehicleType = acsTask.getVehicle_type();
String agv_system_type = acsTask.getAgv_system_type(); // String agv_system_type = acsTask.getAgv_system_type();
//
String start_height = acsTask.getStart_height(); // String start_height = acsTask.getStart_height();
String next_height = acsTask.getNext_height(); // String next_height = acsTask.getNext_height();
String car_type=acsTask.getCar_type(); // String car_type=acsTask.getCar_type();
String car_width=acsTask.getCar_width(); // String car_width=acsTask.getCar_width();
//
//
if (StrUtil.equals(is_send, "0")) { // if (StrUtil.equals(is_send, "0")) {
continue;
}
// //校验路由关系
// List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
// if (ObjectUtils.isEmpty(shortPathsList)) {
// acsTask.setRemark("路由不通无法生成指令");
// taskserver.updateByCodeFromCache(acsTask);
// continue; // continue;
// } // }
// //
// if (!StrUtil.equals(shortPathsList.get(0).getType(), CommonFinalParam.ONE)) { //// //校验路由关系
//// List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
//// if (ObjectUtils.isEmpty(shortPathsList)) {
//// acsTask.setRemark("路由不通无法生成指令");
//// taskserver.updateByCodeFromCache(acsTask);
//// continue;
//// }
////
//// if (!StrUtil.equals(shortPathsList.get(0).getType(), CommonFinalParam.ONE)) {
//// continue;
//// }
//// RouteLineDto routeLineDto = shortPathsList.get(0);
//// String path = routeLineDto.getPath();
//// String type = routeLineDto.getType();
//// String[] str = path.split("->");
//// List<String> pathlist = Arrays.asList(str);
//// int index = 0;
//// for (int m = 0; m < pathlist.size(); m++) {
//// if (pathlist.get(m).equals(start_device_code)) {
//// index = m + 1;
//// break;
//// }
//// }
//// next_device_code = pathlist.get(index);
//
// if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) {
// next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z();
// } else {
// next_point_code = next_device_code;
// }
//
// Instruction instdto = new Instruction();
// instdto.setInstruction_type(task_type);
// instdto.setInstruction_id(IdUtil.simpleUUID());
// instdto.setRoute_plan_code(route_plan_code);
// instdto.setRemark(acsTask.getRemark());
// instdto.setMaterial(acsTask.getMaterial());
// instdto.setQuantity(acsTask.getQuantity());
// instdto.setTask_id(taskid);
// instdto.setTask_code(taskcode);
// instdto.setVehicle_code(vehiclecode);
// String now = DateUtil.now();
// instdto.setCreate_time(now);
// instdto.setCreate_by(SecurityUtils.getCurrentNickName());
//
// instdto.setStart_device_code(start_point_code);
// instdto.setStart_point_code(start_point_code);
// instdto.setPut_device_code(put_device_code);
// instdto.setPut_point_code(put_point_code);
// instdto.setNext_device_code(next_device_code);
// instdto.setNext_point_code(next_point_code);
// instdto.setCar_type(car_type);
// instdto.setCar_width(car_width);
// instdto.setPriority(priority);
// instdto.setInstruction_status(InstructionStatusEnum.READY.getIndex());
// instdto.setExecute_device_code(start_point_code);
// instdto.setVehicle_type(vehicleType);
// instdto.setAgv_system_type(agv_system_type);
// instdto.setStart_height(start_height);
// instdto.setNext_height(next_height);
//
// try {
// instructionService.create(instdto);
// } catch (Exception e) {
// acsTask.setRemark(e.getMessage());
// taskserver.updateByCodeFromCache(acsTask);
// LuceneLogDto logDto = LuceneLogDto.builder()
// .device_code("定时创建指令失败")
// .content(e.getMessage())
// .build();
// logDto.setLog_level(2);
// luceneExecuteLogService.deviceExecuteLog(logDto);
// continue; // continue;
// } // }
// RouteLineDto routeLineDto = shortPathsList.get(0); // //创建指令后修改任务状态
// String path = routeLineDto.getPath(); // acsTask.setTask_status(TaskStatusEnum.BUSY.getIndex());
// String type = routeLineDto.getType(); // acsTask.setUpdate_time(DateUtil.now());
// String[] str = path.split("->"); // taskserver.update(acsTask);
// List<String> pathlist = Arrays.asList(str); //
// int index = 0; // }
// for (int m = 0; m < pathlist.size(); m++) { // }
// if (pathlist.get(m).equals(start_device_code)) {
// index = m + 1;
// break;
// }
// }
// next_device_code = pathlist.get(index);
if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) { /**
next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); * 根据任务状态创建指令、生成下一条指令
} else { */
next_point_code = next_device_code; public void run() throws Exception {
log.info("自动生成指令开始: {}", DateUtil.now());
RLock lock = redissonClient.getLock("autoGenInstructionLock");
boolean locked = false;
try {
locked = lock.tryLock(0, 5, TimeUnit.SECONDS); // 不等待锁持有5秒自动释放
if (!locked) {
log.debug("未获取到分布式锁,跳过本次执行");
return;
} }
TaskService taskserver = SpringContextHolder.getBean(TaskService.class);
Instruction instdto = new Instruction(); InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class);
instdto.setInstruction_type(task_type); DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
instdto.setInstruction_id(IdUtil.simpleUUID()); LuceneExecuteLogService luceneExecuteLogService = SpringContextHolder.getBean(LuceneExecuteLogServiceImpl.class);
instdto.setRoute_plan_code(route_plan_code); //按优先级降序task_code升序
instdto.setRemark(acsTask.getRemark()); List<TaskDto> list = taskserver.queryAllByStatus("0");
instdto.setMaterial(acsTask.getMaterial()); if (CollectionUtils.isEmpty(list)) {
instdto.setQuantity(acsTask.getQuantity()); return;
instdto.setTask_id(taskid); }
instdto.setTask_code(taskcode); Set<String> busyStartPoints = taskserver.queryAllByStatus("1").stream()
instdto.setVehicle_code(vehiclecode); .map(t -> extractStartPoint(t.getStart_device_code()))
String now = DateUtil.now(); .filter(Objects::nonNull)
instdto.setCreate_time(now); .collect(Collectors.toSet());
instdto.setCreate_by(SecurityUtils.getCurrentNickName()); for (TaskDto acsTask : list) {
if (isNonBlockingTaskType(acsTask)) {
instdto.setStart_device_code(start_point_code); continue; // AGV/Truss且不以"-"开头,跳过,继续看下一个
instdto.setStart_point_code(start_point_code); }
instdto.setPut_device_code(put_device_code); if (StrUtil.equals(acsTask.getIs_send(), "0")) {
instdto.setPut_point_code(put_point_code); break;
instdto.setNext_device_code(next_device_code); }
instdto.setNext_point_code(next_point_code); //起始点冲突(同一起点已有执行中任务)
instdto.setCar_type(car_type); String startPoint = extractStartPoint(acsTask.getStart_device_code());
instdto.setCar_width(car_width); if (startPoint != null && busyStartPoints.contains(startPoint)) {
instdto.setPriority(priority); break;
instdto.setInstruction_status(InstructionStatusEnum.READY.getIndex()); }
instdto.setExecute_device_code(start_point_code); try {
instdto.setVehicle_type(vehicleType); createInstruction(acsTask, appService, instructionService, taskserver);
instdto.setAgv_system_type(agv_system_type); } catch (Exception e) {
instdto.setStart_height(start_height); acsTask.setRemark(e.getMessage());
instdto.setNext_height(next_height); taskserver.updateByCodeFromCache(acsTask);
LuceneLogDto logDto = LuceneLogDto.builder()
try { .device_code("定时创建指令失败")
instructionService.create(instdto); .content(e.getMessage())
} catch (Exception e) { .build();
acsTask.setRemark(e.getMessage()); logDto.setLog_level(2);
taskserver.updateByCodeFromCache(acsTask); luceneExecuteLogService.deviceExecuteLog(logDto);
LuceneLogDto logDto = LuceneLogDto.builder() break;
.device_code("定时创建指令失败") }
.content(e.getMessage()) break;
.build(); }
logDto.setLog_level(2); } catch (Exception e) {
luceneExecuteLogService.deviceExecuteLog(logDto); log.error("自动生成指令异常", e);
continue; } finally {
if (locked && lock.isHeldByCurrentThread()) {
try {
lock.unlock();
} catch (Exception e) {
log.error("释放分布式锁异常", e);
}
} }
//创建指令后修改任务状态
acsTask.setTask_status(TaskStatusEnum.BUSY.getIndex());
acsTask.setUpdate_time(DateUtil.now());
taskserver.update(acsTask);
} }
} }
/**
* 判断是否属于无需生成指令的任务类型
*/
private boolean isNonBlockingTaskType(TaskDto acsTask) {
String taskType = acsTask.getTask_type();
String taskCode = acsTask.getTask_code();
boolean isAgv = StrUtil.equals(taskType, TaskTypeEnum.AGV_Task.getIndex())
&& !StrUtil.startWith(taskCode, "-");
boolean isTruss = StrUtil.equals(taskType, TaskTypeEnum.Truss_Task.getIndex())
&& !StrUtil.startWith(taskCode, "-");
return isAgv || isTruss;
}
/**
* 从设备编码中提取起点区域CPRK1, BCPRK2
*/
private String extractStartPoint(String startDeviceCode) {
if (startDeviceCode == null) {
return null;
}
if (startDeviceCode.contains("BCPRK") || startDeviceCode.contains("CPRK")) {
return startDeviceCode.split("-")[0];
}
return null;
}
/**
* 封装指令创建与任务状态更新
*/
private void createInstruction(TaskDto acsTask, DeviceAppService appService,
InstructionService instructionService, TaskService taskserver) throws Exception {
String next_device_code = acsTask.getNext_device_code();
String next_point_code;
if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) {
next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z();
} else {
next_point_code = next_device_code;
}
Instruction instdto = new Instruction();
instdto.setInstruction_type(acsTask.getTask_type());
instdto.setInstruction_id(IdUtil.simpleUUID());
instdto.setRoute_plan_code(acsTask.getRoute_plan_code());
instdto.setRemark(acsTask.getRemark());
instdto.setMaterial(acsTask.getMaterial());
instdto.setQuantity(acsTask.getQuantity());
instdto.setTask_id(acsTask.getTask_id());
instdto.setTask_code(acsTask.getTask_code());
instdto.setVehicle_code(acsTask.getVehicle_code());
instdto.setCreate_time(DateUtil.now());
instdto.setCreate_by(SecurityUtils.getCurrentNickName());
instdto.setStart_device_code(acsTask.getStart_point_code());
instdto.setStart_point_code(acsTask.getStart_point_code());
instdto.setPut_device_code(acsTask.getPut_device_code());
instdto.setPut_point_code(acsTask.getPut_point_code());
instdto.setNext_device_code(next_device_code);
instdto.setNext_point_code(next_point_code);
instdto.setCar_type(acsTask.getCar_type());
instdto.setCar_width(acsTask.getCar_width());
instdto.setPriority(acsTask.getPriority());
instdto.setInstruction_status(InstructionStatusEnum.READY.getIndex());
instdto.setExecute_device_code(acsTask.getStart_point_code());
instdto.setVehicle_type(acsTask.getVehicle_type());
instdto.setAgv_system_type(acsTask.getAgv_system_type());
instdto.setStart_height(acsTask.getStart_height());
instdto.setNext_height(acsTask.getNext_height());
instructionService.create(instdto);
// 更新任务状态为执行中
acsTask.setTask_status(TaskStatusEnum.BUSY.getIndex());
acsTask.setUpdate_time(DateUtil.now());
taskserver.update(acsTask);
}
} }

View File

@@ -6,7 +6,7 @@ spring:
freemarker: freemarker:
check-template-location: false check-template-location: false
profiles: profiles:
active: dev active: prod
# active: prod # active: prod
jackson: jackson:
time-zone: GMT+8 time-zone: GMT+8

View File

@@ -1,11 +1,8 @@
package org.nl.wms.sch_manage.service.util; package org.nl.wms.sch_manage.service.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.nl.wms.sch_manage.enums.TaskStatus; import org.nl.wms.sch_manage.enums.TaskStatus;
@@ -17,7 +14,8 @@ import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.sql.Time; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -30,83 +28,68 @@ import java.util.stream.Collectors;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class AutoTask { public class AutoTask {
private static final ScheduledExecutorService DELAY_EXECUTOR = Executors.newSingleThreadScheduledExecutor();
/** /**
* 任务服务 * 延迟任务调度线程池,从单线程改为适中并发,避免任务堆积
*/ */
private ScheduledExecutorService delayExecutor;
@Autowired @Autowired
private ISchBaseTaskService taskService; private ISchBaseTaskService taskService;
/**
* 任务工厂服务
*/
@Autowired @Autowired
private TaskFactory taskFactory; private TaskFactory taskFactory;
private final RedissonClient redissonClient; private final RedissonClient redissonClient;
//定时任务
@SneakyThrows @PostConstruct
public void run() { public void init() {
RLock lock = redissonClient.getLock(this.getClass().getName()); //无界线程池,线程数
boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS); this.delayExecutor = Executors.newScheduledThreadPool(4);
try { }
if (tryLock) {
sendTask(); @PreDestroy
} public void destroy() {
} catch (Exception e) { if (delayExecutor != null && !delayExecutor.isShutdown()) {
if (tryLock) { delayExecutor.shutdown();
lock.unlock(); try {
if (!delayExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
delayExecutor.shutdownNow();
}
} catch (InterruptedException e) {
delayExecutor.shutdownNow();
Thread.currentThread().interrupt();
} }
} }
} }
/** /**
* 定时下发任务 * 定时任务
*/ */
// private void sendTask() { public void run() {
// List<SchBaseTask> taskList = taskService.list(new LambdaQueryWrapper<SchBaseTask>() RLock lock = redissonClient.getLock(this.getClass().getName());
// .eq(SchBaseTask::getIs_delete, IOSConstant.IS_DELETE_NO) boolean locked = false;
// .eq(SchBaseTask::getTask_status, TaskStatus.CREATE.getCode())); try {
// if (ObjectUtil.isEmpty(taskList)) { //最多等待 1 秒,锁自动释放时间 30 秒
// return; locked = lock.tryLock(2, 30, TimeUnit.SECONDS);
// } if (locked) {
// // 找出需要间隔的任务列表 sendTask();
// List<SchBaseTask> delayTaskList = taskList.stream() } else {
// .filter(r -> "STInTask".equals(r.getConfig_code())) log.debug("未获取到分布式锁,跳过本次执行");
// .collect(Collectors.toList()); }
// List<SchBaseTask> immediatelyTaskList = new ArrayList<>(taskList); } catch (Exception e) {
// immediatelyTaskList.removeAll(delayTaskList); log.error("获取分布式锁或执行任务异常,可能 Redis 不可用", e);
// //优先发送正常的任务列表 } finally {
// if (ObjectUtil.isNotEmpty(immediatelyTaskList)) { // 确保释放锁,且只能释放自己持有的锁
// // 整理下发acs参数 if (locked && lock.isHeldByCurrentThread()) {
// for (SchBaseTask taskDao : immediatelyTaskList) { try {
// //任务优先级 lock.unlock();
// taskDao.setPriority(StringUtils.isBlank(taskDao.getPriority()) ? "1" : taskDao.getPriority()); } catch (Exception e) {
// AbstractTask task = taskFactory.getTask(taskDao.getConfig_code()); log.error("释放分布式锁失败", e);
// task.sendTaskOne(taskDao.getTask_id()); }
// } }
// } }
// //间隔3秒发一个任务 }
// if (ObjectUtil.isNotEmpty(delayTaskList)) {
// DELAY_EXECUTOR.execute(() -> {
// try {
// for (SchBaseTask taskDao : delayTaskList) {
// //间隔3秒发一个任务
// Thread.sleep(2000);
// //任务优先级
// taskDao.setPriority(StringUtils.isBlank(taskDao.getPriority()) ? "1" : taskDao.getPriority());
// AbstractTask task = taskFactory.getTask(taskDao.getConfig_code());
// task.sendTaskOne(taskDao.getTask_id());
// }
// } catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// log.error("延迟任务被中断", e);
// } catch (Exception e) {
// log.error("延迟下发任务执行失败", e);
// }
// });
// }
// }
/** /**
* 定时下发任务 * 定时下发任务
@@ -119,6 +102,7 @@ public class AutoTask {
if (ObjectUtil.isEmpty(taskList)) { if (ObjectUtil.isEmpty(taskList)) {
return; return;
} }
// 2. 统一设置默认优先级并分组 // 2. 统一设置默认优先级并分组
Map<Boolean, List<SchBaseTask>> partitioned = taskList.stream() Map<Boolean, List<SchBaseTask>> partitioned = taskList.stream()
.peek(task -> { .peek(task -> {
@@ -129,38 +113,35 @@ public class AutoTask {
.collect(Collectors.partitioningBy(r -> "STInTask".equals(r.getConfig_code()))); .collect(Collectors.partitioningBy(r -> "STInTask".equals(r.getConfig_code())));
List<SchBaseTask> immediatelyTaskList = partitioned.get(false); List<SchBaseTask> immediatelyTaskList = partitioned.get(false);
List<SchBaseTask> delayTaskList = partitioned.get(true); List<SchBaseTask> delayTaskList = partitioned.get(true);
// 3. 立即下发任务 // 3. 立即下发任务
if (ObjectUtil.isNotEmpty(immediatelyTaskList)) { if (ObjectUtil.isNotEmpty(immediatelyTaskList)) {
//log.info("开始下发立即任务, 数量: {}", immediatelyTaskList.size());
for (SchBaseTask task : immediatelyTaskList) { for (SchBaseTask task : immediatelyTaskList) {
try { try {
AbstractTask taskExecutor = taskFactory.getTask(task.getConfig_code()); AbstractTask taskExecutor = taskFactory.getTask(task.getConfig_code());
taskExecutor.sendTaskOne(task.getTask_id()); taskExecutor.sendTaskOne(task.getTask_id());
// log.info("任务下发成功: taskId={}, configCode={}", task.getTask_id(), task.getConfig_code());
} catch (Exception e) { } catch (Exception e) {
log.error("任务下发失败: taskId={}, configCode={}", task.getTask_id(), task.getConfig_code(), e); log.error("任务下发失败: taskId={}, configCode={}", task.getTask_id(), task.getConfig_code(), e);
} }
} }
//log.info("立即任务下发完成");
} }
// 4. 延迟下发任务(间隔 7 秒,异步执行) // 4. 延迟下发任务(间隔 7 秒,异步执行)
if (ObjectUtil.isNotEmpty(delayTaskList)) { if (ObjectUtil.isNotEmpty(delayTaskList)) {
delayTaskList.sort(Comparator.comparing(SchBaseTask::getTask_code)); delayTaskList.sort(Comparator.comparing(SchBaseTask::getTask_code));
//log.info("开始调度延迟任务, 数量: {}, 间隔: 7秒", delayTaskList.size());
long delaySeconds = 0; long delaySeconds = 0;
for (SchBaseTask task : delayTaskList) { for (SchBaseTask task : delayTaskList) {
DELAY_EXECUTOR.schedule(() -> { delayExecutor.schedule(() -> {
try { try {
AbstractTask taskExecutor = taskFactory.getTask(task.getConfig_code()); AbstractTask taskExecutor = taskFactory.getTask(task.getConfig_code());
taskExecutor.sendTaskOne(task.getTask_id()); taskExecutor.sendTaskOne(task.getTask_id());
log.info("延迟任务下发成功: taskCode={}, configCode={}", task.getTask_code(), task.getConfig_code()); //log.info("延迟任务下发成功: taskCode={}, configCode={}", task.getTask_code(), task.getConfig_code());
} catch (Exception e) { } catch (Exception e) {
log.error("延迟任务下发失败: taskId={}, configCode={}", task.getTask_id(), task.getConfig_code(), e); log.error("延迟任务下发失败: taskId={}, configCode={}", task.getTask_id(), task.getConfig_code(), e);
} }
}, delaySeconds, TimeUnit.SECONDS); }, delaySeconds, TimeUnit.SECONDS);
delaySeconds += 7; delaySeconds += 7;
} }
//log.info("延迟任务已全部提交调度");
} }
} }
} }

View File

@@ -7,6 +7,10 @@ package org.nl.wms.system_manage.enums;
*/ */
public class SysParamConstant { public class SysParamConstant {
/**
* 是否反馈IWMS
*/
public final static String IS_CONNECT_IWMS = "is_connect_iwms";
/** /**
* 是否连接ACS * 是否连接ACS
*/ */

View File

@@ -1,11 +1,9 @@
package org.nl.wms.wbwms.service.impl; package org.nl.wms.wbwms.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.nl.common.exception.BadRequestException; import org.nl.common.exception.BadRequestException;
import org.nl.config.SpringContextHolder; import org.nl.config.SpringContextHolder;
@@ -14,14 +12,12 @@ import org.nl.wms.basedata_manage.service.dao.mapper.MdMeMaterialbaseMapper;
import org.nl.wms.system_manage.enums.SysParamConstant; import org.nl.wms.system_manage.enums.SysParamConstant;
import org.nl.wms.system_manage.service.param.dao.Param; import org.nl.wms.system_manage.service.param.dao.Param;
import org.nl.wms.system_manage.service.param.impl.SysParamServiceImpl; import org.nl.wms.system_manage.service.param.impl.SysParamServiceImpl;
import org.nl.wms.warehouse_manage.enums.IOSConstant;
import org.nl.wms.warehouse_manage.inAndOut.service.dto.TOWMSMSG; import org.nl.wms.warehouse_manage.inAndOut.service.dto.TOWMSMSG;
import org.nl.wms.warehouse_manage.service.dto.CheckToWmsMsg; import org.nl.wms.warehouse_manage.service.dto.CheckToWmsMsg;
import org.nl.wms.warehouse_manage.service.dto.MoveToWmsMsg; import org.nl.wms.warehouse_manage.service.dto.MoveToWmsMsg;
import org.nl.wms.wbwms.enums.WMSConstant; import org.nl.wms.wbwms.enums.WMSConstant;
import org.nl.wms.wbwms.service.IWmsToWmsService; import org.nl.wms.wbwms.service.IWmsToWmsService;
import org.nl.wms.wbwms.service.dto.IWmstoWmsResponse;
import org.nl.wms.wbwms.service.dto.WmstoIWmsResponse;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -75,11 +71,20 @@ public class IWmsToWmsServiceImpl implements IWmsToWmsService {
@Override @Override
public JSONObject FinishOutTask(TOWMSMSG towmsmsg) { public JSONObject FinishOutTask(TOWMSMSG towmsmsg) {
JSONObject result = new JSONObject(); // 系统参数类
SysParamServiceImpl sysParamService = SpringContextHolder.getBean(SysParamServiceImpl.class);
//判断是否反馈IWMS
Param isConnectAcs = sysParamService.findByCode(SysParamConstant.IS_CONNECT_IWMS);
if (ObjectUtil.isNotEmpty(isConnectAcs)) {
if (isConnectAcs.getValue().equals(IOSConstant.IS_DELETE_NO)) {
return null;
}
}
JSONObject result;
// 系统参数类 // 系统参数类
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(towmsmsg), JSONObject.class); JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(towmsmsg), JSONObject.class);
log.info("FinishOutTask请求参数是-------------------" + jsonObject.toString()); log.info("FinishOutTask请求参数是-------------------" + jsonObject.toString());
String wmsUrl = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode(SysParamConstant.WMS_URL).getValue(); String wmsUrl = sysParamService.findByCode(SysParamConstant.WMS_URL).getValue();
wmsUrl = wmsUrl + WMSConstant.INOUT_WMS_API; wmsUrl = wmsUrl + WMSConstant.INOUT_WMS_API;
try { try {
String resultMsg = HttpRequest.post(wmsUrl) String resultMsg = HttpRequest.post(wmsUrl)

View File

@@ -351,7 +351,7 @@ public class WmsToIWmsServiceImpl implements WmsToIWmsService {
for (SchBasePoint point : list) { for (SchBasePoint point : list) {
JSONObject pointData = new JSONObject(); JSONObject pointData = new JSONObject();
pointData.put("point_code", point.getPoint_code()); pointData.put("point_code", point.getPoint_code());
pointData.put("status", point.getPoint_status().equals(IOSEnum.POINT_STATUS.code("空位")) ? "0" : "1"); pointData.put("status", point.getPoint_status().equals(PointStatusEnum.EMPTY_POINT.getCode()) && point.getLock_up()? "0" : "1");
dataList.add(pointData); dataList.add(pointData);
} }
} }

View File

@@ -70,8 +70,11 @@ spring:
connectionMinimumIdleSize: 8 connectionMinimumIdleSize: 8
connectionPoolSize: 8 connectionPoolSize: 8
address: redis://127.0.0.1:6379 address: redis://127.0.0.1:6379
idleConnectionTimeout: 10000 idleConnectionTimeout: 30000
timeout: 3000 timeout: 3000
pingConnectionInterval: 30000
retryAttempts: 3
retryInterval: 1500
# 登录相关配置 # 登录相关配置
login: login:

View File

@@ -11,7 +11,7 @@ spring:
freemarker: freemarker:
check-template-location: false check-template-location: false
profiles: profiles:
active: dev active: prod
jackson: jackson:
time-zone: GMT+8730 885 969 time-zone: GMT+8730 885 969
data: data: