Junjie
8 天以前 9a8018c3fbc94f99d5d184c8cb1ef23d7366cea0
src/main/java/com/zy/core/utils/station/StationRegularDispatchProcessor.java
@@ -25,7 +25,6 @@
import com.zy.core.model.StationObjModel;
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.model.protocol.StationTaskBufferItem;
import com.zy.core.move.StationMoveCoordinator;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.station.model.DispatchLimitConfig;
@@ -41,6 +40,8 @@
@Component
public class StationRegularDispatchProcessor {
    private static final long STATION_IN_SLOW_LOG_THRESHOLD_MS = 500L;
    @Autowired
    private BasDevpService basDevpService;
@@ -265,86 +266,130 @@
        ) {
            return;
        }
        WrkMast wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode()));
        if (wrkMast == null || !Objects.equals(wrkMast.getWrkSts(), WrkStsType.NEW_INBOUND.sts)) {
            return;
        }
        Integer crnNo = wrkMast.getCrnNo();
        BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>().eq("crn_no", crnNo));
        if (basCrnp == null) {
            News.taskInfo(wrkMast.getWrkNo(), "{}工作,未找到堆垛机数据", wrkMast.getWrkNo());
            return;
        }
        int maxInTask = 3;
        if (basCrnp.getMaxInTask() != null) {
            maxInTask = basCrnp.getMaxInTask();
        }
        long count = wrkMastService.count(new QueryWrapper<WrkMast>().eq("crn_no", crnNo).eq("wrk_sts", WrkStsType.INBOUND_STATION_RUN.sts));
        if(count >=  maxInTask) {
            News.taskInfo(wrkMast.getWrkNo(), "{}工作,堆垛机到达任务上限,稍后执行", wrkMast.getWrkNo());
            stationProtocol.setSystemWarning(wrkMast.getWrkNo() + "工作," + crnNo + "号堆垛机到达任务上限,稍后执行");
            return;
        }
        String locNo = wrkMast.getLocNo();
        FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo);
        if (findCrnNoResult == null) {
            News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo());
            return;
        }
        Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId);
        if (targetStationId == null) {
            News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId);
            return;
        }
        DispatchLimitConfig limitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), targetStationId);
        int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
        LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
        LoopHitResult loopHitResult = stationDispatchLoadSupport.findPathLoopHit(
                limitConfig,
                stationProtocol.getStationId(),
                targetStationId,
                loadGuardState
        );
        if (stationDispatchLoadSupport.isDispatchBlocked(limitConfig, currentStationTaskCount, loadGuardState, loopHitResult.isThroughLoop())) {
            return;
        }
        StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0);
        if (command == null) {
            News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo());
            return;
        }
        Date now = new Date();
        wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts);
        wrkMast.setSourceStaNo(stationProtocol.getStationId());
        wrkMast.setStaNo(targetStationId);
        wrkMast.setSystemMsg("");
        wrkMast.setIoTime(now);
        wrkMast.setModiTime(now);
        if (wrkMastService.updateById(wrkMast)) {
            wrkAnalysisService.markInboundStationStart(wrkMast, now);
            boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "stationInExecute");
            if (offered && stationMoveCoordinator != null) {
                stationMoveCoordinator.recordDispatch(
                        wrkMast.getWrkNo(),
                        stationProtocol.getStationId(),
                        "stationInExecute",
                        command,
                        false
                );
        long totalStartNs = System.nanoTime();
        Map<String, Long> stepCostMap = new java.util.LinkedHashMap<>();
        WrkMast wrkMast = null;
        Integer targetStationId = null;
        String targetSource = "unknown";
        String locNo = null;
        try {
            long stepStartNs = System.nanoTime();
            wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode()));
            stepCostMap.put("loadWrkByBarcode", elapsedMillis(stepStartNs));
            if (wrkMast == null || !Objects.equals(wrkMast.getWrkSts(), WrkStsType.NEW_INBOUND.sts)) {
                return;
            }
            News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command));
            redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5);
            loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
            stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
            Integer crnNo = wrkMast.getCrnNo();
            BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>().eq("crn_no", crnNo));
            if (basCrnp == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,未找到堆垛机数据", wrkMast.getWrkNo());
                return;
            }
            int maxInTask = 3;
            if (basCrnp.getMaxInTask() != null) {
                maxInTask = basCrnp.getMaxInTask();
            }
            stepStartNs = System.nanoTime();
            long count = wrkMastService.count(new QueryWrapper<WrkMast>().eq("crn_no", crnNo).eq("wrk_sts", WrkStsType.INBOUND_STATION_RUN.sts));
            stepCostMap.put("countCrnInboundRunTask", elapsedMillis(stepStartNs));
            if(count >=  maxInTask) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,堆垛机到达任务上限,稍后执行", wrkMast.getWrkNo());
                stationProtocol.setSystemWarning(wrkMast.getWrkNo() + "工作," + crnNo + "号堆垛机到达任务上限,稍后执行");
                return;
            }
            locNo = wrkMast.getLocNo();
            stepStartNs = System.nanoTime();
            FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo);
            stepCostMap.put("resolveCrnByLocNo", elapsedMillis(stepStartNs));
            if (findCrnNoResult == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo());
                return;
            }
            stepStartNs = System.nanoTime();
            CommonService.InStationResolveResult resolveResult = commonService.resolveInStationId(findCrnNoResult, stationId);
            stepCostMap.put("resolveInboundTargetStation", elapsedMillis(stepStartNs));
            targetStationId = resolveResult == null ? null : resolveResult.getTargetStationId();
            targetSource = resolveResult == null ? "unknown" : (resolveResult.isCacheHit() ? "cache" : "search");
            if (targetStationId == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId);
                return;
            }
            stepStartNs = System.nanoTime();
            DispatchLimitConfig limitConfig = stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), targetStationId);
            int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
            LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
            stepCostMap.put("buildLoopGuardState", elapsedMillis(stepStartNs));
            stepStartNs = System.nanoTime();
            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0);
            stepCostMap.put("buildMoveCommand", elapsedMillis(stepStartNs));
            if (command == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo());
                return;
            }
            stepStartNs = System.nanoTime();
            LoopHitResult loopHitResult = stationDispatchLoadSupport.findPathLoopHitByNavigatePath(command.getNavigatePath(), loadGuardState);
            stepCostMap.put("evaluateLoopPath", elapsedMillis(stepStartNs));
            if (stationDispatchLoadSupport.isDispatchBlocked(limitConfig, currentStationTaskCount, loadGuardState, loopHitResult.isThroughLoop())) {
                return;
            }
            stepStartNs = System.nanoTime();
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts);
            wrkMast.setSourceStaNo(stationProtocol.getStationId());
            wrkMast.setStaNo(targetStationId);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markInboundStationStart(wrkMast, now);
                // 先记录 session 再入队命令,避免消费线程在 session 写入 Redis 前取到命令导致路由校验失败。
                if (stationMoveCoordinator != null) {
                    stationMoveCoordinator.recordDispatch(
                            wrkMast.getWrkNo(),
                            stationProtocol.getStationId(),
                            "stationInExecute",
                            command,
                            false
                    );
                }
                boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "stationInExecute");
                if (offered) {
                    News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command));
                } else {
                    News.warn("输送站点入库命令入队被拒绝(可能重复),站点号={},工作号={}", stationId, wrkMast.getWrkNo());
                }
                redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5);
                loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
            }
            stepCostMap.put("updateWrkAndDispatch", elapsedMillis(stepStartNs));
        } finally {
            long totalCostMs = elapsedMillis(totalStartNs);
            if (totalCostMs >= STATION_IN_SLOW_LOG_THRESHOLD_MS) {
                News.warn("stationInExecute耗时较长,stationId={},barcode={},wrkNo={},locNo={},targetStaNo={},targetSource={},stepCosts={},totalCost={}ms",
                        stationId,
                        stationProtocol.getBarcode(),
                        wrkMast == null ? null : wrkMast.getWrkNo(),
                        locNo,
                        targetStationId,
                        targetSource,
                        JSON.toJSONString(stepCostMap),
                        totalCostMs);
            }
        }
    }
    private long elapsedMillis(long startNs) {
        long elapsedNs = System.nanoTime() - startNs;
        return elapsedNs <= 0L ? 0L : elapsedNs / 1_000_000L;
    }
}