| New file |
| | |
| | | # 输送站重规划执行管道重构设计 |
| | | |
| | | ## 1. 目标 |
| | | |
| | | 本次改动只处理 `StationOperateProcessUtils` 中输送站重新计算路径、堵塞恢复、排序放行、绕圈监控相关逻辑的结构重构。 |
| | | |
| | | 目标如下: |
| | | |
| | | - 统一 `checkStationRunBlock`、`checkStationIdleRecover`、`checkStationOutOrder`、`watchCircleStation` 四条链路中的重规划执行流程。 |
| | | - 把“目标站决策”和“命令派发副作用”从入口扫描逻辑中拆开,降低后续维护复杂度。 |
| | | - 在不改变现有业务语义的前提下,固定重规划的执行顺序,减少遗漏校验、遗漏清理、遗漏状态同步的风险。 |
| | | - 保持现有 `ZyStationV5Thread`、`StationMoveCoordinator`、Redis key、WMS 交互、出库排序/绕圈规则不变。 |
| | | |
| | | ## 2. 非目标 |
| | | |
| | | 以下内容不在本次范围内: |
| | | |
| | | - 不修改 `ZyStationV5Thread#getRunBlockRerouteCommand` 的候选路径选择算法。 |
| | | - 不修改 `resolveOutboundDispatchDecision` 的业务判断结果,只允许重构其调用方式。 |
| | | - 不调整 `StationMoveCoordinator` 的会话模型与 Redis 结构。 |
| | | - 不新增新的运行时服务类,不把逻辑拆出 `StationOperateProcessUtils` 到独立组件。 |
| | | - 不借本次重构修复潜在业务问题或补充新的兜底分支。 |
| | | |
| | | ## 3. 现状 |
| | | |
| | | 当前 `StationOperateProcessUtils` 已超过 2200 行,以下四条链路存在明显重复: |
| | | |
| | | - `checkStationRunBlock` |
| | | - `checkStationIdleRecover` |
| | | - `checkStationOutOrder` |
| | | - `watchCircleStation` |
| | | |
| | | 这些方法内部都在做相似的事情: |
| | | |
| | | - 加载 `WrkMast`、`pathLenFactor`、`outOrderList` |
| | | - 解析下一目标站 |
| | | - 判断是否跳过本次重规划 |
| | | - 生成命令 |
| | | - 清理旧 session / 旧分段命令 / idle 期间旧下发命令 |
| | | - 派发命令 |
| | | - 同步绕圈观察状态 |
| | | - 记录 `StationMoveCoordinator` 派发会话 |
| | | |
| | | 但是它们把“扫描候选站点”和“执行重规划”混写在一起,导致: |
| | | |
| | | - 相同保护条件出现在多个入口中,后续变更容易漏改。 |
| | | - 派发前后的副作用顺序分散在不同方法里,难以确认一致性。 |
| | | - 运行堵塞、停留超时、排序放行、绕圈监控之间的差异点被淹没在重复流程里。 |
| | | |
| | | ## 4. 选择方案 |
| | | |
| | | 采用“统一重规划执行管道”的方案: |
| | | |
| | | - 四个入口方法继续保留,各自只负责扫描符合条件的候选站点。 |
| | | - 新增一套内部上下文与执行计划模型,把重规划过程统一成固定流程: |
| | | - `loadContext` |
| | | - `resolveDecision` |
| | | - `buildCommandPlan` |
| | | - `executePlan` |
| | | - `applyEffects` |
| | | - 场景差异通过内部枚举和上下文字段表达,不通过新建多个对外服务类表达。 |
| | | |
| | | 不采用“只抽几个私有方法”的方案,因为那样无法真正收口流程顺序,只会把重复代码换一种位置继续存在。 |
| | | |
| | | 不采用“拆成多个独立 service”的方案,因为当前仓库缺少既有测试护栏,这种拆分会放大变更面,不符合本次“现有行为尽量不变、只重构结构”的目标。 |
| | | |
| | | ## 5. 设计 |
| | | |
| | | ### 5.1 总体结构 |
| | | |
| | | `StationOperateProcessUtils` 内部新增以下私有结构: |
| | | |
| | | - `RerouteSceneType` |
| | | - 表示四种场景: |
| | | - 运行堵塞重算 |
| | | - 停留超时重算 |
| | | - 出库排序重算 |
| | | - 绕圈监控重算 |
| | | - `RerouteContext` |
| | | - 收口当前场景执行所需的输入,包括: |
| | | - `BasDevp` |
| | | - `StationThread` |
| | | - `StationProtocol` |
| | | - `WrkMast` |
| | | - `outOrderList` |
| | | - `pathLenFactor` |
| | | - 当前场景类型 |
| | | - 是否需要 runBlock 专用命令 |
| | | - 是否需要重置分段命令 |
| | | - 是否需要清理 idle 期间旧命令 |
| | | - 派发场景名与日志上下文 |
| | | - `RerouteDecision` |
| | | - 表示本次是否继续执行重规划,以及解析得到的目标信息: |
| | | - `targetStationId` |
| | | - 是否绕圈 |
| | | - `OutOrderDispatchDecision` |
| | | - `StationTaskLoopService.LoopEvaluation` |
| | | - 是否应记录 loop issue |
| | | - `RerouteCommandPlan` |
| | | - 表示命令生成与派发计划: |
| | | - 最终 `StationCommand` |
| | | - 派发前动作 |
| | | - 派发后动作 |
| | | - 日志内容 |
| | | |
| | | 这些结构只在 `StationOperateProcessUtils` 内部使用,不新增新的对外接口。 |
| | | |
| | | ### 5.2 统一主流程 |
| | | |
| | | 统一后的重规划执行流程固定为五步: |
| | | |
| | | 1. `loadContext` |
| | | - 由入口方法完成最小筛选后构造 `RerouteContext` |
| | | - 补齐 `WrkMast`、`pathLenFactor`、`outOrderList` |
| | | - 记录当前场景后续需要的控制标志 |
| | | |
| | | 2. `resolveDecision` |
| | | - 统一判断本次是否应该继续执行 |
| | | - 统一解析下一目标站 |
| | | - 统一附带绕圈/loop 信息 |
| | | - 对运行堵塞场景保留两条原有路径: |
| | | - 入库重分配库位 |
| | | - 普通堵塞重算路线 |
| | | |
| | | 3. `buildCommandPlan` |
| | | - 根据场景决定命令生成方式: |
| | | - 普通运行堵塞重算继续使用 `getRunBlockRerouteCommand` |
| | | - 其它场景继续使用 `buildOutboundMoveCommand` |
| | | - 收口派发前动作: |
| | | - 是否 `cancelSession` |
| | | - 是否 `resetSegmentMoveCommandsBeforeReroute` |
| | | - 是否清理 idle 期间旧下发命令 |
| | | |
| | | 4. `executePlan` |
| | | - 统一处理公共保护: |
| | | - 当前 buffer 是否仍含本任务命令 |
| | | - idle recover 是否因最近刚派发而跳过 |
| | | - 是否需要申请 out-order dispatch lock |
| | | - 是否命中短时去重派发 |
| | | |
| | | 5. `applyEffects` |
| | | - 统一处理派发成功后的副作用: |
| | | - `syncOutOrderWatchState` |
| | | - `stationMoveCoordinator.recordDispatch` |
| | | - idle track 回写 |
| | | - 场景专属日志 |
| | | |
| | | ### 5.3 四个入口方法的职责边界 |
| | | |
| | | 四个入口方法保留,但只负责“筛选候选站点”,不再各自拼装完整重规划流程。 |
| | | |
| | | #### `checkStationRunBlock` |
| | | |
| | | 负责: |
| | | |
| | | - 扫描 `autoing + loading + taskNo > 0 + runBlock = true` 的站点 |
| | | - 获取任务与 runBlock 锁 |
| | | - 把候选站点送入统一管道 |
| | | |
| | | 场景内部保留原有差异: |
| | | |
| | | - 入库且站点位于 `runBlockReassignLocStationList` 时,继续走“重新分配库位并直连派发”分支。 |
| | | - 其它情况继续走“重新计算路线”分支。 |
| | | |
| | | #### `checkStationIdleRecover` |
| | | |
| | | 负责: |
| | | |
| | | - 扫描 `autoing + loading + taskNo > 0 + !runBlock` 的站点 |
| | | - 仅在当前站点已到达当前决策点时进入后续判定 |
| | | - 把候选站点送入统一管道 |
| | | |
| | | 保留原行为: |
| | | |
| | | - 使用 `StationTaskIdleTrack` |
| | | - 使用“最近刚派发则跳过”的保护 |
| | | - 派发前清理 idle 期间旧 `BasStationOpt` |
| | | |
| | | #### `checkStationOutOrder` |
| | | |
| | | 负责: |
| | | |
| | | - 扫描配置在 `outOrderList` 中、当前停在排序决策点且仍需继续放行的站点 |
| | | - 把候选站点送入统一管道 |
| | | |
| | | 保留原行为: |
| | | |
| | | - 使用 `resolveOutboundDispatchDecision` |
| | | - 使用 out-order dispatch lock |
| | | - 进入公共副作用时同步绕圈观察状态 |
| | | |
| | | #### `watchCircleStation` |
| | | |
| | | 负责: |
| | | |
| | | - 扫描当前命中 `WATCH_CIRCLE_STATION_` 观察目标的站点 |
| | | - 只有在真正到达下一决策点时才继续执行 |
| | | - 把候选站点送入统一管道 |
| | | |
| | | 保留原行为: |
| | | |
| | | - 继续使用 `resolveOutboundDispatchDecision` |
| | | - 继续复用出库排序的派发与观察状态同步逻辑 |
| | | |
| | | ### 5.4 场景差异的表达方式 |
| | | |
| | | 统一执行骨架不意味着抹平场景差异,差异只在以下位置保留: |
| | | |
| | | - 决策来源不同: |
| | | - runBlock 入库重分配库位来自 WMS 返回结果 |
| | | - 其它场景来自 `resolveOutboundDispatchDecision` 或任务原目标站 |
| | | - 命令构建方式不同: |
| | | - runBlock 普通重算使用 `getRunBlockRerouteCommand` |
| | | - 其它场景使用 `buildOutboundMoveCommand` |
| | | - 派发前动作不同: |
| | | - idle recover 额外清理 idle 期间旧下发命令 |
| | | - outOrder / watchCircle 需要 out-order dispatch lock |
| | | - 派发后副作用不同: |
| | | - runBlock 入库重分配需要更新库位与任务 |
| | | - idle recover 需要回写 `StationTaskIdleTrack` |
| | | - outOrder / watchCircle 需要同步绕圈观察状态 |
| | | |
| | | 差异只存在于场景策略,不再散落于各入口主流程中。 |
| | | |
| | | ## 6. 链路检查 |
| | | |
| | | ### 6.1 输入 |
| | | |
| | | - `BasDevp` 中的出库排序站点配置与运行堵塞重分配站点配置 |
| | | - `StationThread` 当前站点状态 |
| | | - `StationProtocol` 当前站点任务、堵塞、装载状态 |
| | | - `WrkMast` 当前任务状态 |
| | | - `StationMoveCoordinator` 当前会话 |
| | | - Redis 中的 runBlock / idle / outOrder / watchCircle 辅助状态 |
| | | |
| | | ### 6.2 处理流程 |
| | | |
| | | - 入口方法扫描候选站点 |
| | | - 构建 `RerouteContext` |
| | | - 解析 `RerouteDecision` |
| | | - 生成 `RerouteCommandPlan` |
| | | - 执行公共保护 |
| | | - 派发命令 |
| | | - 应用派发后的场景副作用 |
| | | |
| | | ### 6.3 状态变化 |
| | | |
| | | - 命令派发前的 session 取消、分段命令重置、旧命令清理顺序固定化 |
| | | - 观察状态与 move session 记录仍在原有 Redis / coordinator 结构中变化 |
| | | - 不新增新的持久化表与 Redis key 类型 |
| | | |
| | | ### 6.4 输出 |
| | | |
| | | - 成功时输出与当前场景一致的 `StationCommand` |
| | | - 保持原有日志语义 |
| | | - 保持原有 `StationMoveCoordinator` 和 `WATCH_CIRCLE_STATION_` 相关状态推进 |
| | | |
| | | ### 6.5 上下游影响 |
| | | |
| | | - 上游插件调用点不变,仍由 `NormalProcess`、`GslProcess`、`XiaosongProcess`、`FakeProcess` 调用原入口方法 |
| | | - 下游 `StationThread`、`ZyStationV5Thread`、`MessageQueue` 接口不变 |
| | | - `StationMoveCoordinator`、`StationTaskLoopService`、`BasStationOptService` 接口不变 |
| | | |
| | | ## 7. 风险与保护 |
| | | |
| | | ### 7.1 风险 |
| | | |
| | | - 如果重构时把“入口筛选”和“场景执行”边界切错,可能导致某些站点提前进入重规划流程。 |
| | | - 如果派发前副作用顺序改变,可能引入 session 状态、旧分段命令、idle 清理不一致的问题。 |
| | | - 如果公共层错误吸收了场景差异,可能改变 runBlock 入库重分配与普通 reroute 的行为。 |
| | | |
| | | ### 7.2 保护 |
| | | |
| | | - 入口扫描条件保持原样,先只做搬迁,不做判定收紧或放宽。 |
| | | - runBlock 入库重分配场景单独保留,不强行并入普通 reroute 命令生成。 |
| | | - 派发前后副作用顺序由统一模板固定,但步骤内容沿用现有实现。 |
| | | - 不改线程侧路径重规划算法,不改 Redis key 命名,不改 WMS 接口交互。 |
| | | |
| | | ## 8. 验证 |
| | | |
| | | 当前仓库已确认没有现成 `src/test/java` 与测试依赖,因此验证分为两层: |
| | | |
| | | 1. 新增最小测试基建 |
| | | - 补充 `spring-boot-starter-test` |
| | | - 为统一重规划执行骨架补定向单测 |
| | | |
| | | 2. 定向回归验证 |
| | | - 运行堵塞普通重算仍使用 `getRunBlockRerouteCommand` |
| | | - idle recover 在“最近刚派发”场景仍会跳过 |
| | | - outOrder / watchCircle 进入同一执行骨架,但候选筛选条件不同 |
| | | - buffer 中仍有当前任务命令时不会重复派发 |
| | | - 派发成功后 `syncOutOrderWatchState` 与 `recordDispatch` 的触发条件保持不变 |
| | | |
| | | 3. 编译与测试命令 |
| | | - `mvn -q -DskipTests compile` |
| | | - 新增的定向测试命令 |
| | | - 如环境允许,再执行 `mvn test` |
| | | |
| | | ## 9. 实施清单 |
| | | |
| | | - 重构 `src/main/java/com/zy/core/utils/StationOperateProcessUtils.java` |
| | | - 在类内新增统一重规划上下文、决策、命令计划结构 |
| | | - 收口 `checkStationRunBlock` |
| | | - 收口 `checkStationIdleRecover` |
| | | - 收口 `checkStationOutOrder` |
| | | - 收口 `watchCircleStation` |
| | | - 补充最小测试依赖与定向测试 |
| | | |
| | | ## 10. 假设与未验证前提 |
| | | |
| | | - 用户已明确确认本次以“现有行为尽量不变、只重构结构”为主。 |
| | | - 用户已明确确认 `checkStationRunBlock`、`checkStationIdleRecover`、`checkStationOutOrder`、`watchCircleStation` 四条链路一起统一。 |
| | | - 当前未验证所有现场 Redis 状态与历史异常数据分布,设计按现有正常流程组织。 |
| | | - 当前未验证本地完整测试基建是否已存在,需在实施阶段实际补充并执行后确认。 |