From 63b01db83d9aad8a15276b4236a9a22e4aeef065 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 05 五月 2026 12:30:59 +0800
Subject: [PATCH] # Agent数据分析V3.0.1.7
---
src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java | 626 +++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 430 insertions(+), 196 deletions(-)
diff --git a/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java b/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
index f72ce6a..1833aa5 100644
--- a/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
+++ b/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
@@ -21,6 +21,7 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.move.StationMoveCoordinator;
+import com.zy.core.move.StationMoveSession;
import com.zy.core.thread.StationThread;
import com.zy.core.utils.station.model.DispatchLimitConfig;
import com.zy.core.utils.station.model.LoadGuardState;
@@ -28,7 +29,9 @@
import com.zy.core.utils.station.model.OutOrderDispatchDecision;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Value;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -37,7 +40,10 @@
@Component
public class StationOutboundDispatchProcessor {
- private static final int PENDING_DISPATCH_EXPIRE_SECONDS = 60 * 10;
+ private static final int PENDING_DISPATCH_EXPIRE_SECONDS = 60 * 60 * 24;
+ private static final long DEFAULT_PENDING_DISCOVER_TIMEOUT_MS = 60_000L;
+ private static final long DEFAULT_PENDING_SESSION_PROTECT_MS = 90_000L;
+ private static final long DEFAULT_RECENT_DISPATCH_PROTECT_MS = 60_000L;
@Autowired
private WrkMastService wrkMastService;
@@ -57,87 +63,176 @@
private StationDispatchLoadSupport stationDispatchLoadSupport;
@Autowired
private StationOutboundDecisionSupport stationOutboundDecisionSupport;
+ @Autowired
+ private StationDispatchRuntimeStateSupport stationDispatchRuntimeStateSupport;
- public void crnStationOutExecute() {
- try {
- List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
- .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
- .isNotNull("crn_no"));
- for (WrkMast wrkMast : wrkMasts) {
- crnStationOutExecute(wrkMast);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
+ @Value("${station.outbound.pending-discover-timeout-seconds:60}")
+ private long pendingDiscoverTimeoutSeconds;
+ @Value("${station.outbound.pending-session-protect-seconds:90}")
+ private long pendingSessionProtectSeconds;
+ @Value("${station.outbound.recent-dispatch-protect-seconds:60}")
+ private long recentDispatchProtectSeconds;
public void crnStationOutExecute(WrkMast wrkMast) {
try {
if (wrkMast == null || wrkMast.getWrkNo() == null) {
return;
}
- Object pendingObj = redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkMast.getWrkNo());
- if (pendingObj != null) {
- if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN_COMPLETE.sts)) {
- clearPendingDispatch(wrkMast.getWrkNo());
- return;
- }
-
- StationObjModel pendingStationObjModel = getOutboundSourceStation(wrkMast);
- if (pendingStationObjModel == null
- || pendingStationObjModel.getDeviceNo() == null
- || pendingStationObjModel.getStationId() == null) {
- clearPendingDispatch(wrkMast.getWrkNo());
- return;
- }
-
- StationThread pendingStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, pendingStationObjModel.getDeviceNo());
- if (pendingStationThread != null) {
- List<Integer> taskNoList = pendingStationThread.getAllTaskNoList();
- if (taskNoList != null && taskNoList.contains(wrkMast.getWrkNo())) {
- Date now = new Date();
- wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
- wrkMast.setSystemMsg("");
- wrkMast.setIoTime(now);
- wrkMast.setModiTime(now);
- if (wrkMastService.updateById(wrkMast)) {
- wrkAnalysisService.markOutboundStationStart(wrkMast, now);
- notifyUtils.notify(String.valueOf(SlaveType.Devp), pendingStationObjModel.getDeviceNo(),
- String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(),
- NotifyMsgType.STATION_OUT_TASK_RUN, null);
- clearPendingDispatch(wrkMast.getWrkNo());
- News.info("杈撻�佽澶囧凡鍙戠幇浠诲姟鍙凤紝浠诲姟杞繍琛屼腑銆俤eviceNo={}锛屾簮绔�={}锛屽伐浣滃彿={}",
- pendingStationObjModel.getDeviceNo(), pendingStationObjModel.getStationId(), wrkMast.getWrkNo());
- }
- return;
- }
- }
-
- long createdAt;
- try {
- createdAt = Long.parseLong(String.valueOf(pendingObj));
- } catch (Exception ignore) {
- createdAt = System.currentTimeMillis();
- }
- if (System.currentTimeMillis() - createdAt < 15_000L) {
- return;
- }
- clearPendingDispatch(wrkMast.getWrkNo());
- News.warn("杈撻�佺珯鐐规墽琛岃秴鏃讹紝宸查噴鏀鹃噸璇曡祫鏍笺�傚伐浣滃彿={}", wrkMast.getWrkNo());
+ if (shouldStopAfterPendingDispatchCheck(wrkMast)) {
+ return;
}
+ dispatchCrnStationOutTask(wrkMast);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ public void confirmPendingCrnStationOutDispatch(WrkMast wrkMast) {
+ try {
+ shouldStopAfterPendingDispatchCheck(wrkMast);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void dispatchNextCrnStationOutTask(Integer sourceStationId) {
+ try {
+ if (sourceStationId == null) {
+ return;
+ }
+ List<WrkMast> sameSourceTaskList = loadCrnOutboundCompleteTasksBySourceStation(sourceStationId);
+ if (sameSourceTaskList.isEmpty()) {
+ return;
+ }
+ WrkMast dispatchCandidate = null;
+ int pendingTaskCount = 0;
+ int dispatchableTaskCount = 0;
+ for (WrkMast sameSourceTask : sameSourceTaskList) {
+ if (sameSourceTask == null || sameSourceTask.getWrkNo() == null) {
+ continue;
+ }
+ if (hasPendingDispatch(sameSourceTask.getWrkNo())) {
+ pendingTaskCount++;
+ continue;
+ }
+ dispatchableTaskCount++;
+ if (dispatchCandidate == null) {
+ dispatchCandidate = sameSourceTask;
+ }
+ }
+ if (dispatchCandidate == null) {
+ return;
+ }
+ if (dispatchableTaskCount > 1) {
+ News.taskError(dispatchCandidate.getWrkNo(),
+ "鍑哄簱寮傚父锛氬悓涓�婧愮珯瀛樺湪澶氱瑪寰呬笅鍙戞惉杩愬畬鎴愪换鍔★紝涓嶄笅鍙戝懡浠ゃ�傛簮绔�={}锛屽緟涓嬪彂鏁伴噺={}锛屽緟纭鏁伴噺={}",
+ sourceStationId, dispatchableTaskCount, pendingTaskCount);
+ return;
+ }
+ if (pendingTaskCount > 0 || sameSourceTaskList.size() > 1) {
+ News.info("婧愮珯鍑哄簱鍊欓�変换鍔″凡纭畾銆傛簮绔�={}锛屽�欓�夊伐浣滃彿={}锛屽緟纭鏁伴噺={}锛屽緟涓嬪彂鏁伴噺={}",
+ sourceStationId,
+ dispatchCandidate.getWrkNo(),
+ pendingTaskCount,
+ dispatchableTaskCount);
+ }
+ dispatchCrnStationOutTask(dispatchCandidate);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private boolean shouldStopAfterPendingDispatchCheck(WrkMast wrkMast) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null) {
+ return true;
+ }
+ Object pendingDispatchMarker = redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkMast.getWrkNo());
+ if (pendingDispatchMarker == null) {
+ return false;
+ }
+ return processPendingDispatch(wrkMast, pendingDispatchMarker);
+ }
+
+ private boolean processPendingDispatch(WrkMast wrkMast, Object pendingDispatchMarker) {
+ if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN_COMPLETE.sts)) {
+ clearPendingDispatch(wrkMast);
+ return true;
+ }
+
+ StationObjModel sourceStationObjModel = getOutboundSourceStation(wrkMast);
+ if (sourceStationObjModel == null
+ || sourceStationObjModel.getDeviceNo() == null
+ || sourceStationObjModel.getStationId() == null) {
+ clearPendingDispatch(wrkMast);
+ return true;
+ }
+
+ StationThread sourceStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, sourceStationObjModel.getDeviceNo());
+ if (sourceStationThread != null) {
+ List<Integer> taskNoList = sourceStationThread.getAllTaskNoList();
+ if (taskNoList != null && taskNoList.contains(wrkMast.getWrkNo())) {
+ Date now = new Date();
+ wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
+ wrkMast.setSystemMsg("");
+ wrkMast.setIoTime(now);
+ wrkMast.setModiTime(now);
+ if (wrkMastService.updateById(wrkMast)) {
+ wrkAnalysisService.markOutboundStationStart(wrkMast, now);
+ notifyUtils.notify(String.valueOf(SlaveType.Devp), sourceStationObjModel.getDeviceNo(),
+ String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(),
+ NotifyMsgType.STATION_OUT_TASK_RUN, null);
+ clearPendingDispatch(wrkMast);
+ News.info("杈撻�佽澶囧凡鍙戠幇浠诲姟鍙凤紝浠诲姟杞繍琛屼腑銆俤eviceNo={}锛屾簮绔�={}锛屽伐浣滃彿={}",
+ sourceStationObjModel.getDeviceNo(), sourceStationObjModel.getStationId(), wrkMast.getWrkNo());
+ }
+ return true;
+ }
+ }
+
+ long createdAt;
+ try {
+ createdAt = Long.parseLong(String.valueOf(pendingDispatchMarker));
+ } catch (Exception ignore) {
+ createdAt = System.currentTimeMillis();
+ }
+ long pendingDiscoverTimeoutMs = resolvePendingDiscoverTimeoutMs();
+ if (System.currentTimeMillis() - createdAt < pendingDiscoverTimeoutMs) {
+ return true;
+ }
+
+ PendingDispatchGuardResult guardResult = evaluatePendingDispatchGuard(wrkMast, sourceStationObjModel, sourceStationThread);
+ if (guardResult.keepPending()) {
+ News.info("杈撻�佺珯鐐圭瓑寰呮簮绔欐墽琛岃秴鏃跺悗缁х画淇濇寔绛夊緟銆傚伐浣滃彿={}锛屾簮绔�={}锛屽師鍥�={}",
+ wrkMast.getWrkNo(),
+ sourceStationObjModel.getStationId(),
+ guardResult.reason());
+ markPendingDispatch(wrkMast.getWrkNo());
+ return true;
+ }
+ clearPendingDispatch(wrkMast);
+ News.warn("杈撻�佺珯鐐规墽琛岀‘璁よ秴鏃讹紝涓旀湭鍙戠幇鏈夋晥娲诲姩閾捐矾锛屽凡閲婃斁閲嶈瘯璧勬牸銆傚伐浣滃彿={}", wrkMast.getWrkNo());
+ return false;
+ }
+
+ public void dualCrnStationOutExecute(WrkMast wrkMast) {
+ try {
+ if (wrkMast == null || wrkMast.getWrkNo() == null) {
+ return;
+ }
+ if (hasPendingDispatch(wrkMast.getWrkNo())) {
+ return;
+ }
StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
return;
}
-
StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
if (stationThread == null) {
return;
}
Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
- StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId());
+ StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId());
if (stationProtocol == null) {
return;
}
@@ -147,146 +242,39 @@
return;
}
- if (!(stationProtocol.isAutoing()
+ if (stationProtocol.isAutoing()
&& stationProtocol.isLoading()
- && stationProtocol.getTaskNo() == 0)) {
- return;
- }
-
- Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
- List<Integer> outOrderList = stationOutboundDecisionSupport.getAllOutOrderList();
- OutOrderDispatchDecision dispatchDecision =
- stationOutboundDecisionSupport.resolveOutboundDispatchDecision(
- stationProtocol.getStationId(),
- wrkMast,
- outOrderList,
- pathLenFactor
- );
- Integer moveStaNo = dispatchDecision == null ? null : dispatchDecision.getTargetStationId();
- if (moveStaNo == null) {
- return;
- }
-
- DispatchLimitConfig limitConfig =
- stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo);
- int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
- LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
- LoopHitResult loopHitResult =
- stationDispatchLoadSupport.findPathLoopHit(
- limitConfig,
- stationProtocol.getStationId(),
- moveStaNo,
- loadGuardState,
- wrkMast,
- pathLenFactor
- );
- if (stationDispatchLoadSupport.isDispatchBlocked(
- limitConfig,
- currentStationTaskCount,
- loadGuardState,
- loopHitResult.isThroughLoop())) {
- return;
- }
-
- StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
- stationThread,
- wrkMast,
- stationProtocol.getStationId(),
- moveStaNo,
- pathLenFactor
- );
- if (command == null) {
- News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
- return;
- }
-
- boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
- if (!offered) {
- return;
- }
- if (stationMoveCoordinator != null) {
- stationMoveCoordinator.recordDispatch(
- wrkMast.getWrkNo(),
+ && stationProtocol.getTaskNo() == 0) {
+ Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
+ StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
+ stationThread,
+ wrkMast,
stationProtocol.getStationId(),
- "crnStationOutExecute",
- command,
- false
+ wrkMast.getStaNo(),
+ pathLenFactor
);
- }
- markPendingDispatch(wrkMast.getWrkNo());
- News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎵ц銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
- stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
- redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
- loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
- stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void dualCrnStationOutExecute() {
- try {
- List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
- .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
- .isNotNull("dual_crn_no"));
- for (WrkMast wrkMast : wrkMasts) {
- if (hasPendingDispatch(wrkMast.getWrkNo())) {
- continue;
- }
- StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
- if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
- continue;
- }
- StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
- if (stationThread == null) {
- continue;
+ if (command == null) {
+ News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
+ return;
}
- Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
- StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId());
- if (stationProtocol == null) {
- continue;
+ boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "dualCrnStationOutExecute");
+ if (!offered) {
+ return;
}
-
- Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
- if (lock != null) {
- continue;
- }
-
- if (stationProtocol.isAutoing()
- && stationProtocol.isLoading()
- && stationProtocol.getTaskNo() == 0) {
- Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
- StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
- stationThread,
- wrkMast,
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
stationProtocol.getStationId(),
- wrkMast.getStaNo(),
- pathLenFactor
+ "dualCrnStationOutExecute",
+ command,
+ false
);
- if (command == null) {
- News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
- continue;
- }
-
- boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "dualCrnStationOutExecute");
- if (!offered) {
- continue;
- }
- if (stationMoveCoordinator != null) {
- stationMoveCoordinator.recordDispatch(
- wrkMast.getWrkNo(),
- stationProtocol.getStationId(),
- "dualCrnStationOutExecute",
- command,
- false
- );
- }
- markPendingDispatch(wrkMast.getWrkNo());
- News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎺ュ崟銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
- stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
- redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
}
+ markPendingDispatch(wrkMast.getWrkNo());
+ News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎺ュ崟銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
+ stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
+ redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
}
} catch (Exception e) {
e.printStackTrace();
@@ -303,14 +291,131 @@
if (wrkMast == null || wrkMast.getSourceStaNo() == null) {
return null;
}
- BasStation basStation = basStationService.getById(wrkMast.getSourceStaNo());
+ return getOutboundSourceStation(wrkMast.getSourceStaNo());
+ }
+
+ private StationObjModel getOutboundSourceStation(Integer sourceStationId) {
+ if (sourceStationId == null) {
+ return null;
+ }
+ BasStation basStation = basStationService.getById(sourceStationId);
if (basStation == null || basStation.getDeviceNo() == null) {
return null;
}
StationObjModel stationObjModel = new StationObjModel();
- stationObjModel.setStationId(wrkMast.getSourceStaNo());
+ stationObjModel.setStationId(sourceStationId);
stationObjModel.setDeviceNo(basStation.getDeviceNo());
return stationObjModel;
+ }
+
+ private void dispatchCrnStationOutTask(WrkMast wrkMast) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null) {
+ return;
+ }
+ StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
+ if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
+ return;
+ }
+
+ StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
+ if (stationThread == null) {
+ return;
+ }
+
+ Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
+ StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId());
+ if (stationProtocol == null) {
+ return;
+ }
+
+ Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
+ if (lock != null) {
+ return;
+ }
+
+ if (!(stationProtocol.isAutoing()
+ && stationProtocol.isLoading()
+ && stationProtocol.getTaskNo() == 0)) {
+ return;
+ }
+
+ Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
+ List<Integer> outOrderList = stationOutboundDecisionSupport.getAllOutOrderList();
+ OutOrderDispatchDecision dispatchDecision =
+ stationOutboundDecisionSupport.resolveOutboundDispatchDecision(
+ stationProtocol.getStationId(),
+ wrkMast,
+ outOrderList,
+ pathLenFactor
+ );
+ Integer moveStaNo = dispatchDecision == null ? null : dispatchDecision.getTargetStationId();
+ if (moveStaNo == null) {
+ return;
+ }
+
+ DispatchLimitConfig limitConfig =
+ stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo);
+ int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
+ LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
+ LoopHitResult loopHitResult =
+ stationDispatchLoadSupport.findPathLoopHit(
+ limitConfig,
+ stationProtocol.getStationId(),
+ moveStaNo,
+ loadGuardState,
+ wrkMast,
+ pathLenFactor
+ );
+ if (stationDispatchLoadSupport.isDispatchBlocked(
+ limitConfig,
+ currentStationTaskCount,
+ loadGuardState,
+ loopHitResult.isThroughLoop())) {
+ return;
+ }
+
+ StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
+ stationThread,
+ wrkMast,
+ stationProtocol.getStationId(),
+ moveStaNo,
+ pathLenFactor
+ );
+ if (command == null) {
+ News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
+ return;
+ }
+
+ boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
+ if (!offered) {
+ return;
+ }
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "crnStationOutExecute",
+ command,
+ false
+ );
+ }
+ markPendingDispatch(wrkMast.getWrkNo());
+ News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎵ц銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
+ stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
+ redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
+ loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
+ stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
+ }
+
+ private List<WrkMast> loadCrnOutboundCompleteTasksBySourceStation(Integer sourceStationId) {
+ if (sourceStationId == null) {
+ return new ArrayList<>();
+ }
+ return wrkMastService.list(new QueryWrapper<WrkMast>()
+ .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
+ .eq("source_sta_no", sourceStationId)
+ .isNotNull("crn_no")
+ .orderByAsc("io_time", "wrk_no"));
}
private boolean hasPendingDispatch(Integer wrkNo) {
@@ -330,4 +435,133 @@
}
redisUtil.del(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkNo);
}
+
+ private void clearPendingDispatch(WrkMast wrkMast) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null) {
+ return;
+ }
+ clearPendingDispatch(wrkMast.getWrkNo());
+ }
+
+ private PendingDispatchGuardResult evaluatePendingDispatchGuard(WrkMast wrkMast,
+ StationObjModel stationObjModel,
+ StationThread stationThread) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null || stationObjModel == null || stationObjModel.getStationId() == null) {
+ return PendingDispatchGuardResult.release("missing-runtime-context");
+ }
+ if (hasActiveMoveSession(wrkMast.getWrkNo(), stationObjModel.getStationId())) {
+ return PendingDispatchGuardResult.keep("active-session");
+ }
+ if (hasRecentSuccessfulDispatch(wrkMast.getWrkNo(), stationObjModel.getStationId())) {
+ return PendingDispatchGuardResult.keep("recent-successful-dispatch");
+ }
+ if (taskExistsInBuffer(stationThread, wrkMast.getWrkNo())) {
+ return PendingDispatchGuardResult.keep("task-buffer-detected");
+ }
+ return PendingDispatchGuardResult.release("no-active-chain");
+ }
+
+ private boolean hasActiveMoveSession(Integer wrkNo, Integer sourceStationId) {
+ if (wrkNo == null || wrkNo <= 0 || stationMoveCoordinator == null || sourceStationId == null) {
+ return false;
+ }
+ StationMoveSession session = stationMoveCoordinator.loadSession(wrkNo);
+ if (session == null || !session.isActive()) {
+ return false;
+ }
+ if (!Objects.equals(sourceStationId, session.getDispatchStationId())) {
+ return false;
+ }
+ long now = System.currentTimeMillis();
+ Long lastIssuedAt = session.getLastIssuedAt();
+ if (lastIssuedAt != null && now - lastIssuedAt <= resolvePendingSessionProtectMs()) {
+ return true;
+ }
+ Long updatedAt = session.getUpdatedAt();
+ return updatedAt != null && now - updatedAt <= resolvePendingSessionProtectMs();
+ }
+
+ private boolean hasRecentSuccessfulDispatch(Integer wrkNo, Integer sourceStationId) {
+ if (stationDispatchRuntimeStateSupport == null) {
+ return false;
+ }
+ return stationDispatchRuntimeStateSupport.hasRecentIssuedMoveCommand(
+ wrkNo,
+ sourceStationId,
+ resolveRecentDispatchProtectMs()
+ );
+ }
+
+ private boolean taskExistsInBuffer(StationThread stationThread, Integer wrkNo) {
+ if (stationThread == null || wrkNo == null || wrkNo <= 0) {
+ return false;
+ }
+ Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
+ if (statusMap == null || statusMap.isEmpty()) {
+ return false;
+ }
+ for (StationProtocol stationProtocol : statusMap.values()) {
+ if (stationProtocol == null || stationProtocol.getTaskBufferItems() == null) {
+ continue;
+ }
+ if (containsTaskNo(stationProtocol, wrkNo)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean containsTaskNo(StationProtocol stationProtocol, Integer wrkNo) {
+ if (stationProtocol == null || stationProtocol.getTaskBufferItems() == null || wrkNo == null) {
+ return false;
+ }
+ return stationProtocol.getTaskBufferItems().stream()
+ .filter(Objects::nonNull)
+ .anyMatch(item -> Objects.equals(wrkNo, item.getTaskNo()));
+ }
+
+ private long resolvePendingDiscoverTimeoutMs() {
+ return resolveMillis(pendingDiscoverTimeoutSeconds, DEFAULT_PENDING_DISCOVER_TIMEOUT_MS);
+ }
+
+ private long resolvePendingSessionProtectMs() {
+ return resolveMillis(pendingSessionProtectSeconds, DEFAULT_PENDING_SESSION_PROTECT_MS);
+ }
+
+ private long resolveRecentDispatchProtectMs() {
+ return resolveMillis(recentDispatchProtectSeconds, DEFAULT_RECENT_DISPATCH_PROTECT_MS);
+ }
+
+ private long resolveMillis(long seconds, long defaultMs) {
+ if (seconds <= 0L) {
+ return defaultMs;
+ }
+ return seconds * 1000L;
+ }
+
+ private static class PendingDispatchGuardResult {
+ private final boolean keepPending;
+ private final String reason;
+
+ private PendingDispatchGuardResult(boolean keepPending, String reason) {
+ this.keepPending = keepPending;
+ this.reason = reason;
+ }
+
+ public static PendingDispatchGuardResult keep(String reason) {
+ return new PendingDispatchGuardResult(true, reason);
+ }
+
+ public static PendingDispatchGuardResult release(String reason) {
+ return new PendingDispatchGuardResult(false, reason);
+ }
+
+ public boolean keepPending() {
+ return keepPending;
+ }
+
+ public String reason() {
+ return reason;
+ }
+ }
}
--
Gitblit v1.9.1