From 720e0926fa1c94b952c26e111206c5d6e1ed5ba2 Mon Sep 17 00:00:00 2001
From: lsh <lsh@163.com>
Date: 星期二, 21 四月 2026 15:59:49 +0800
Subject: [PATCH] Merge branch 'master' of http://47.97.1.152:5880/r/zy-wcs-master
---
src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java | 125 +++++++++++++++++++++++++++++++++++------
1 files changed, 105 insertions(+), 20 deletions(-)
diff --git a/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java b/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
index 02018dd..f6073dc 100644
--- a/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
+++ b/src/main/java/com/zy/core/utils/station/StationOutboundDecisionSupport.java
@@ -26,6 +26,7 @@
import com.zy.core.thread.StationThread;
import com.zy.core.utils.station.model.CircleTargetCandidate;
import com.zy.core.utils.station.model.OutOrderDispatchDecision;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -37,8 +38,14 @@
import java.util.Map;
import java.util.Objects;
+@Slf4j
@Component
public class StationOutboundDecisionSupport {
+
+ private static final long PATH_CALC_SLOW_THRESHOLD_MS = 50L;
+ private static final long OUT_ORDER_DECISION_SLOW_THRESHOLD_MS = 100L;
+ private static final long CURRENT_OUT_ORDER_DECISION_SLOW_THRESHOLD_MS = 100L;
+ private static final long CIRCLE_TARGET_EVAL_SLOW_THRESHOLD_MS = 100L;
@Autowired
private WrkMastService wrkMastService;
@@ -113,6 +120,7 @@
WrkMast wrkMast,
List<Integer> outOrderStationIds,
Double pathLenFactor) {
+ long startMs = System.currentTimeMillis();
if (wrkMast == null || wrkMast.getStaNo() == null) {
return null;
}
@@ -120,6 +128,7 @@
if (!shouldApplyOutOrder(wrkMast, outOrderStationIds)) {
return OutOrderDispatchDecision.direct(wrkMast.getStaNo());
}
+ long resolveDispatchTargetStartMs = System.currentTimeMillis();
Integer dispatchStationId = resolveDispatchOutOrderTarget(
wrkMast,
wrkMast.getSourceStaNo(),
@@ -128,18 +137,33 @@
pathLenFactor,
decisionPathCache
);
+ long resolveDispatchTargetCostMs = System.currentTimeMillis() - resolveDispatchTargetStartMs;
if (dispatchStationId == null) {
return null;
}
- if (isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache)) {
- return resolveCurrentOutOrderDispatchDecision(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache);
- }
- if (!Objects.equals(dispatchStationId, wrkMast.getStaNo())
+ long currentDispatchCheckStartMs = System.currentTimeMillis();
+ boolean currentOutOrderDispatchStation = isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache);
+ long currentDispatchCheckCostMs = System.currentTimeMillis() - currentDispatchCheckStartMs;
+ OutOrderDispatchDecision decision;
+ if (currentOutOrderDispatchStation) {
+ decision = resolveCurrentOutOrderDispatchDecision(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache);
+ } else if (!Objects.equals(dispatchStationId, wrkMast.getStaNo())
&& isCurrentOutOrderStation(currentStationId, outOrderStationIds)
&& isWatchingCircleArrival(wrkMast.getWrkNo(), currentStationId)) {
- return OutOrderDispatchDecision.circle(dispatchStationId, null, false);
+ decision = OutOrderDispatchDecision.circle(dispatchStationId, null, false);
+ } else {
+ decision = OutOrderDispatchDecision.direct(dispatchStationId);
}
- return OutOrderDispatchDecision.direct(dispatchStationId);
+ long totalCostMs = System.currentTimeMillis() - startMs;
+ log.info("resolveOutboundDispatchDecision profile, taskNo={}, currentStationId={}, finalTargetStationId={}, dispatchStationId={}, currentOutOrderDispatchStation={}, decision={}, circle={}, resolveDispatchTargetCostMs={}ms, currentDispatchCheckCostMs={}ms, totalCostMs={}ms",
+ wrkMast.getWrkNo(), currentStationId, wrkMast.getStaNo(), dispatchStationId, currentOutOrderDispatchStation,
+ decision == null ? null : decision.getTargetStationId(), decision != null && decision.isCircle(),
+ resolveDispatchTargetCostMs, currentDispatchCheckCostMs, totalCostMs);
+ if (totalCostMs > OUT_ORDER_DECISION_SLOW_THRESHOLD_MS) {
+ log.warn("resolveOutboundDispatchDecision slow, taskNo={}, currentStationId={}, totalCostMs={}ms, resolveDispatchTargetCostMs={}ms, currentDispatchCheckCostMs={}ms",
+ wrkMast.getWrkNo(), currentStationId, totalCostMs, resolveDispatchTargetCostMs, currentDispatchCheckCostMs);
+ }
+ return decision;
}
public void syncOutOrderWatchState(WrkMast wrkMast,
@@ -207,26 +231,39 @@
Integer targetStationId,
Double pathLenFactor,
DecisionPathCache decisionPathCache) {
+ long startMs = System.currentTimeMillis();
Double normalizedFactor = normalizePathLenFactor(pathLenFactor);
Integer currentTaskNo = wrkMast == null ? null : wrkMast.getWrkNo();
+ boolean cacheHit = false;
+ List<NavigateNode> path;
if (decisionPathCache == null) {
- if (currentTaskNo == null) {
- return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor);
+ path = currentTaskNo == null
+ ? navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor)
+ : navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
+ } else {
+ String cacheKey = buildPathCacheKey(currentTaskNo, sourceStationId, targetStationId, normalizedFactor);
+ List<NavigateNode> cachedPath = decisionPathCache.pathMap.get(cacheKey);
+ if (cachedPath != null) {
+ cacheHit = true;
+ path = cachedPath;
+ } else {
+ path = currentTaskNo == null
+ ? navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor)
+ : navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
+ if (path == null) {
+ path = Collections.emptyList();
+ }
+ decisionPathCache.pathMap.put(cacheKey, path);
}
- return navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
}
- String cacheKey = buildPathCacheKey(currentTaskNo, sourceStationId, targetStationId, normalizedFactor);
- List<NavigateNode> cachedPath = decisionPathCache.pathMap.get(cacheKey);
- if (cachedPath != null) {
- return cachedPath;
- }
- List<NavigateNode> path = currentTaskNo == null
- ? navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, null, normalizedFactor)
- : navigateUtils.calcOptimalPathByStationId(sourceStationId, targetStationId, currentTaskNo, normalizedFactor);
if (path == null) {
path = Collections.emptyList();
}
- decisionPathCache.pathMap.put(cacheKey, path);
+ long costMs = System.currentTimeMillis() - startMs;
+ if (costMs > PATH_CALC_SLOW_THRESHOLD_MS) {
+ log.warn("calcOutboundNavigatePath slow, taskNo={}, sourceStationId={}, targetStationId={}, pathCacheHit={}, pathNodeCount={}, pathCostMs={}ms",
+ currentTaskNo, sourceStationId, targetStationId, cacheHit, path.size(), costMs);
+ }
return path;
}
@@ -301,10 +338,12 @@
List<Integer> outOrderStationIds,
Double pathLenFactor,
DecisionPathCache decisionPathCache) {
+ long startMs = System.currentTimeMillis();
if (!isCurrentOutOrderDispatchStation(currentStationId, wrkMast, outOrderStationIds, pathLenFactor, decisionPathCache)) {
return null;
}
+ long batchQueryStartMs = System.currentTimeMillis();
List<WrkMast> batchWrkList = wrkMastService.list(new QueryWrapper<WrkMast>()
.eq("io_type", WrkIoType.OUT.id)
.notIn("wrk_sts",
@@ -314,6 +353,7 @@
.eq("batch", wrkMast.getBatch())
.orderByAsc("batch_seq")
.orderByAsc("wrk_no"));
+ long batchQueryCostMs = System.currentTimeMillis() - batchQueryStartMs;
if (batchWrkList.isEmpty()) {
return OutOrderDispatchDecision.direct(wrkMast.getStaNo());
}
@@ -326,26 +366,36 @@
}
List<NavigateNode> initPath;
+ long initPathStartMs = System.currentTimeMillis();
try {
initPath = calcOutboundNavigatePath(wrkMast, wrkMast.getSourceStaNo(), wrkMast.getStaNo(), pathLenFactor, decisionPathCache);
} catch (Exception e) {
News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 璁$畻鎺掑簭璺緞澶辫触锛屽綋鍓嶇珯鐐�={}", wrkMast.getBatch(), currentStationId);
return null;
}
+ long initPathCostMs = System.currentTimeMillis() - initPathStartMs;
+ long batchSeqScanStartMs = System.currentTimeMillis();
Integer seq = getOutStationBatchSeq(initPath, currentStationId, wrkMast.getBatch());
+ long batchSeqScanCostMs = System.currentTimeMillis() - batchSeqScanStartMs;
boolean toTarget = seq == null
? currentBatchSeq.equals(wrkMast.getBatchSeq())
: Integer.valueOf(seq + 1).equals(wrkMast.getBatchSeq());
if (toTarget) {
- if (hasReachableOutReleaseSlot(wrkMast, currentStationId, wrkMast.getStaNo(), pathLenFactor, decisionPathCache)) {
+ long releaseSlotCheckStartMs = System.currentTimeMillis();
+ boolean hasReachableReleaseSlot = hasReachableOutReleaseSlot(wrkMast, currentStationId, wrkMast.getStaNo(), pathLenFactor, decisionPathCache);
+ long releaseSlotCheckCostMs = System.currentTimeMillis() - releaseSlotCheckStartMs;
+ if (hasReachableReleaseSlot) {
return OutOrderDispatchDecision.direct(wrkMast.getStaNo());
}
+ long loopEvalStartMs = System.currentTimeMillis();
StationTaskLoopService.LoopEvaluation loopEvaluation = evaluateOutOrderLoop(
wrkMast.getWrkNo(),
currentStationId,
outOrderStationIds
);
+ long loopEvalCostMs = System.currentTimeMillis() - loopEvalStartMs;
+ long circleTargetEvalStartMs = System.currentTimeMillis();
Integer circleTarget = resolveNextCircleOrderTarget(
wrkMast,
currentStationId,
@@ -354,6 +404,15 @@
pathLenFactor,
decisionPathCache
);
+ long circleTargetEvalCostMs = System.currentTimeMillis() - circleTargetEvalStartMs;
+ long totalCostMs = System.currentTimeMillis() - startMs;
+ log.info("resolveCurrentOutOrderDispatchDecision profile, taskNo={}, currentStationId={}, batch={}, currentBatchSeq={}, taskBatchSeq={}, toTarget={}, batchQueryCostMs={}ms, initPathCostMs={}ms, batchSeqScanCostMs={}ms, releaseSlotCheckCostMs={}ms, loopEvalCostMs={}ms, circleTargetEvalCostMs={}ms, totalCostMs={}ms, circleTarget={}",
+ wrkMast.getWrkNo(), currentStationId, wrkMast.getBatch(), currentBatchSeq, wrkMast.getBatchSeq(), toTarget,
+ batchQueryCostMs, initPathCostMs, batchSeqScanCostMs, releaseSlotCheckCostMs, loopEvalCostMs, circleTargetEvalCostMs, totalCostMs, circleTarget);
+ if (totalCostMs > CURRENT_OUT_ORDER_DECISION_SLOW_THRESHOLD_MS) {
+ log.warn("resolveCurrentOutOrderDispatchDecision slow, taskNo={}, currentStationId={}, totalCostMs={}ms, batchQueryCostMs={}ms, initPathCostMs={}ms, batchSeqScanCostMs={}ms, releaseSlotCheckCostMs={}ms, circleTargetEvalCostMs={}ms",
+ wrkMast.getWrkNo(), currentStationId, totalCostMs, batchQueryCostMs, initPathCostMs, batchSeqScanCostMs, releaseSlotCheckCostMs, circleTargetEvalCostMs);
+ }
if (circleTarget == null) {
News.taskInfo(wrkMast.getWrkNo(), "鐩爣绔欏綋鍓嶄笉鍙繘锛屼笖鏈壘鍒板彲鎵ц鐨勪笅涓�鎺掑簭妫�娴嬬偣锛屽綋鍓嶇珯鐐�={}", currentStationId);
return null;
@@ -361,11 +420,14 @@
return OutOrderDispatchDecision.circle(circleTarget, loopEvaluation, true);
}
+ long loopEvalStartMs = System.currentTimeMillis();
StationTaskLoopService.LoopEvaluation loopEvaluation = evaluateOutOrderLoop(
wrkMast.getWrkNo(),
currentStationId,
outOrderStationIds
);
+ long loopEvalCostMs = System.currentTimeMillis() - loopEvalStartMs;
+ long circleTargetEvalStartMs = System.currentTimeMillis();
Integer circleTarget = resolveNextCircleOrderTarget(
wrkMast,
currentStationId,
@@ -374,6 +436,15 @@
pathLenFactor,
decisionPathCache
);
+ long circleTargetEvalCostMs = System.currentTimeMillis() - circleTargetEvalStartMs;
+ long totalCostMs = System.currentTimeMillis() - startMs;
+ log.info("resolveCurrentOutOrderDispatchDecision profile, taskNo={}, currentStationId={}, batch={}, currentBatchSeq={}, taskBatchSeq={}, toTarget={}, batchQueryCostMs={}ms, initPathCostMs={}ms, batchSeqScanCostMs={}ms, loopEvalCostMs={}ms, circleTargetEvalCostMs={}ms, totalCostMs={}ms, circleTarget={}",
+ wrkMast.getWrkNo(), currentStationId, wrkMast.getBatch(), currentBatchSeq, wrkMast.getBatchSeq(), toTarget,
+ batchQueryCostMs, initPathCostMs, batchSeqScanCostMs, loopEvalCostMs, circleTargetEvalCostMs, totalCostMs, circleTarget);
+ if (totalCostMs > CURRENT_OUT_ORDER_DECISION_SLOW_THRESHOLD_MS) {
+ log.warn("resolveCurrentOutOrderDispatchDecision slow, taskNo={}, currentStationId={}, totalCostMs={}ms, batchQueryCostMs={}ms, initPathCostMs={}ms, batchSeqScanCostMs={}ms, circleTargetEvalCostMs={}ms",
+ wrkMast.getWrkNo(), currentStationId, totalCostMs, batchQueryCostMs, initPathCostMs, batchSeqScanCostMs, circleTargetEvalCostMs);
+ }
if (circleTarget == null) {
News.taskInfo(wrkMast.getWrkNo(), "鏈壘鍒板彲鎵ц鐨勪笅涓�鎺掑簭妫�娴嬬偣锛屽綋鍓嶇珯鐐�={}", currentStationId);
return null;
@@ -496,6 +567,7 @@
Integer expectedLoopIssueCount,
Double pathLenFactor,
DecisionPathCache decisionPathCache) {
+ long startMs = System.currentTimeMillis();
if (currentStationId == null || orderedOutStationList == null || orderedOutStationList.size() <= 1) {
return null;
}
@@ -503,6 +575,8 @@
int startIndex = orderedOutStationList.indexOf(currentStationId);
int total = orderedOutStationList.size();
List<CircleTargetCandidate> candidateList = new ArrayList<>();
+ int minPathLen = Integer.MAX_VALUE;
+ int maxPathLen = 0;
for (int offset = 1; offset < total; offset++) {
int candidateIndex = (startIndex + offset + total) % total;
Integer candidateStationId = orderedOutStationList.get(candidateIndex);
@@ -513,6 +587,8 @@
List<NavigateNode> path = calcOutboundNavigatePath(wrkMast, currentStationId, candidateStationId, pathLenFactor, decisionPathCache);
if (path != null && !path.isEmpty()) {
candidateList.add(new CircleTargetCandidate(candidateStationId, path.size(), offset));
+ minPathLen = Math.min(minPathLen, path.size());
+ maxPathLen = Math.max(maxPathLen, path.size());
}
} catch (Exception ignore) {
}
@@ -539,7 +615,16 @@
return Integer.compare(left.getOffset(), right.getOffset());
}
});
- return resolveGradualCircleTargetByPathLength(expectedLoopIssueCount, candidateList, pathLenFactor);
+ Integer circleTarget = resolveGradualCircleTargetByPathLength(expectedLoopIssueCount, candidateList, pathLenFactor);
+ long totalCostMs = System.currentTimeMillis() - startMs;
+ log.info("resolveNextCircleOrderTarget profile, taskNo={}, currentStationId={}, candidateCount={}, successfulCandidateCount={}, selectedTargetStationId={}, minPathLen={}, maxPathLen={}, totalCostMs={}ms",
+ wrkMast == null ? null : wrkMast.getWrkNo(), currentStationId, Math.max(total - 1, 0), candidateList.size(), circleTarget,
+ minPathLen == Integer.MAX_VALUE ? 0 : minPathLen, maxPathLen, totalCostMs);
+ if (totalCostMs > CIRCLE_TARGET_EVAL_SLOW_THRESHOLD_MS) {
+ log.warn("resolveNextCircleOrderTarget slow, taskNo={}, currentStationId={}, successfulCandidateCount={}, selectedTargetStationId={}, totalCostMs={}ms",
+ wrkMast == null ? null : wrkMast.getWrkNo(), currentStationId, candidateList.size(), circleTarget, totalCostMs);
+ }
+ return circleTarget;
}
private Integer resolveGradualCircleTargetByPathLength(Integer expectedLoopIssueCount,
--
Gitblit v1.9.1