--- name: lockResource 责任链重构 overview: 将 MachineTaskDispatchCenter#lockResource 中自「容器目标站点过滤」起至「厂商负载校验 canDispatchChain」的资源过滤与获取逻辑抽成可排序的责任链组件;新增统一 Runner 收口执行上下文、失败后批量维护 machine_task_resource_wait、整条路径成功并完成子任务落库后按任务链清空等待。 todos: - id: domain-context content: 新增 resourcechain:Context、ChainOutcome、ChainHandler、ResourceLockPhaseRunner(失败写入等待、SHORT_CIRCUIT 分支) status: pending - id: handlers-extract content: 自容器目标站点起至 canDispatchChain 拆为 Ordered handlers,等价迁移日志与状态机/releaseResources status: pending - id: dao-wait content: 新增 MachineTaskResourceWaitMapper + IService,实现 replaceWaits / removeByChain status: pending - id: wire-center content: 精简 MachineTaskDispatchCenter#lockResource:READY 前移 + Runner + 成功后 removeByChain status: pending - id: spring-config content: ResourceLockChainConfiguration 注册 Handler 列表与 Runner status: pending - id: compile content: mvn compile 校验 baoshi-robot-core 模块 status: pending isProject: false --- # lockResource 资源责任链重构计划 ## 范围(已确认) **决策回填(与用户答复 1.D / 2.A 对齐)** - **1.D(自定义链起点)**:责任链 **从「容器目标站点过滤」代码段开始**,其前的进行中/就绪短路、`READY` 状态机、`initStart`、以及获得 `containerStat` 的 RPC 仍在 [`MachineTaskDispatchCenter`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/core\/MachineTaskDispatchCenter.java) 内完成后再进入 Runner。 - **2.A(等待表全套)**:**新增 Mapper + Service + Impl**,覆盖失败时 **`replaceWaits`**、`lockResource` 业务全流程成功并完成子任务落库后 **`removeByChain`**(见下文)。 - **链起点**:与当前代码一致,自「容器目标站点过滤」[`MachineTaskDispatchCenter.java`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/core\/MachineTaskDispatchCenter.java) 开始(在此前仍为链状态 READY 转移等非链逻辑)。 - **链终点(进入任务生成前一刻)**:保持与现实现等价——覆盖至 **`tryLockResource` + `collectVendorResource` + 提升机选取 + `canDispatchChain`**(`factory.createTasks` / `saveBatch` 仍在调度中心收口,不把「持久化子任务」当作链节点)。 - **等待表**:补齐 **Mapper + Service**,实现失败后写入、`lockResource` 整体成功末尾删除(见下文)。 ```mermaid flowchart LR ctx[ChainContext] H1[ContainerTargetStationFilter] H2[ContainerLocationRules] H3[PreCheckLoadSpin] H4[HK_ReleaseWakeDefer] H5[TargetZoneShortcut] H6[StationQueueEnqueue] H7[TryLockLocationOrContainer] H8[ElevatorSelect] H9[VendorLoadCheck] H1 --> H2 --> H3 --> H4 --> H5 --> H6 --> H7 --> H8 --> H9 runner[ResourceLockPhaseRunner] runner --> ctx ``` ## 核心设计 ### 1. 上下文 `ResourceLockChainContext` 新建包建议 [`baoshi-robot-core/src/main/java/com/baoshi/robot/core/resourcechain/`](baoshi-robot-core/src/main/java/com/baoshi/robot/core/resourcechain/),承载:`MachineTaskChain`(需随流程刷新如 `elevatorId` 更新后用 `machineTaskChainService.getByCode` 再对齐)、`initStart`、`LocationResourceDataVO containerStat`、`LockResourceDTO`、`VendorResource`、以及 **待写入等待表条目集合**(如 `List` 或由轻量 `(resourceType, resourceCode)` DTO)。 依赖通过构造注入或上下文工厂创建时注入:`MachineTaskChainStateMachine`、`machineTask*` Service、`RPC API`、`elevator/station balancer`、`factory`、`strategyMap` 等沿用调度中心既有 Bean(Runner 接收这些依赖或由 `@Configuration` 组装)。 ### 2. Handler 接口与执行语义 - 定义 `ChainHandler#handle(ResourceLockChainContext ctx)` → 明确结果类型:`CONTINUE` | `SHORT_CIRCUIT_FALSE`(现 `lockResource` 返回 `false`,含 CLOSED/WAITING/唤醒退让等已在具体分支写好的状态迁移) | `SHORT_CIRCUIT_SUCCESS_TO_TASKS`(即通过 `canDispatchChain`,将进入 `createTasks`)。 - 责任链 **`ResourceLockPhaseRunner`(你说的 filter 统一入口)**: - 按 Spring `@Order` 或显式列表顺序遍历 Handler; - 遇到 `SHORT_CIRCUIT_FALSE`:调用 **失败后处理**:`releaseResources(chain)`(按现有等价条件)、按需 **`replaceResourceWaits(chain, ctx收集的等待条目)`**(先按 `warehouse + chainCode` 物理/逻辑清空再批量插入,保证幂等); - 遇到 `SHORT_CIRCUIT_SUCCESS_TO_TASKS`:**不删除等待**,将上下文交回调度中心; - 任意 `SHORT_CIRCUIT_FALSE`:**不删除等待记录**(或仅保留刚写入的失败等待,按计划为「写入等待」)。 ### 3. 与调度中心拆分 [`MachineTaskDispatchCenter#lockResource`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/core\/MachineTaskDispatchCenter.java): - **保留**:`IN_PROGRESS`/`READY` 短路、`initStart`、进入链前的第一次 `READY` 状态机、`releaseResources`、`factory.createTasks` + `machineTaskService.saveBatch` + 更新 `firstTaskVendor`。 - **改为**:在完成 `READY` 转移并获得 `topChain`、`containerStat` RPC 就绪后,`ResourceLockPhaseRunner.run(ctx)`; - **`lockResource` 返回 `true` 前**(且在 `saveBatch` 等业务成功后):调用 **`IMachineTaskResourceWaitService.removeByChain(warehouse, chainCode)`**,保证「已成功获取并完成子任务落库」再清等待。 - **`SHORT_CIRCUIT_FALSE`** 中与现逻辑一致:**不要**在此处删等待(与「失败后记录」并存)。 ### 4. Handler 粒度(与现行代码段落一一对应) 将当前 `lockResource` 中段按顺序拆为独立类(均放在 `resourcechain/handlers/`,文件名示例): | 顺序 | 来源片段 | 说明 | |:---:|:---|:---| |1|容器目标站点过滤|CLOSED| |2|容器位置 + 出库/MOVE 分支对 EXIT_STATION|WAITING/CLOSED| |`preCheckLoad` 自旋|WAITING|| |HK 释放唤醒退让|WAITING + wake|| |库区目标短路完成|COMPLETED + false|| |工作站 `enqueue`|WAITING|| |`tryLockResource`|WAITING + release|| |提升机 LOCK/BALANCE|WAITING + release|| |`canDispatchChain`|WAITING + release|| 抽取时 **逐行等价迁移**(日志、状态机转移、`releaseResources` 调用顺序与条件保持一致),仅在出口统一走 Runner 的失败/成功分支。 ### 5. `machine_task_resource_wait` 持久层 参考现有风格 [`MachineTaskMapper.java`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/repository\/machineTask\/mapper\/MachineTaskMapper.java) / [`IMachineTaskService`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/repository\/machineTask\/service\/IMachineTaskService.java): - 新增 **`MachineTaskResourceWaitMapper`**(`extends BaseMapper`)。 - 新增 **`IMachineTaskResourceWaitService` + Impl**: - `replaceWaits(String warehouse, String chainCode, List rows)`:删除该链未逻辑删记录后批量插入(或 `deleted` 标记清理后插入,与同项目 BaseEntity/MyBatisPlus 惯例一致)。 - `removeByChain(String warehouse, String chainCode)`:成功收尾删除。 - 等待项与 [`MachineTaskResourceTypeEnum`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-common-data\/src\/main\/java\/com\/baoshi\/data\/machineTask\/enums\/MachineTaskResourceTypeEnum.java) 对齐:**站点排队失败 → `STATION` + targetCode**;**提升机不可用 → `ELEVATOR`**;**库位/容器锁定 RPC 失败** → **`CONTAINER`**(`resourceCode = sourceContainer`,若你希望区分库区可后续扩展枚举)。 - Mapper 需在 MyBatis `@MapperScan` 已扫描的包路径下注册(与同模块 Mapper 保持一致)。 ### 6. Spring 组装 新增 `@Configuration` 类(如 `ResourceLockChainConfiguration`)声明有序的 `List` Bean,`ResourceLockPhaseRunner` 注入该列表。 ### 7. 验证(执行阶段) 执行方案阶段在项目根跑一次 **Maven 编译/类型等价检查**:`mvn -pl baoshi-robot/baoshi-robot-core -am compile -q`(或仓库统一脚本),不改行为前提下保证无编译错误。 ## 关键文件一览 | 动作 | 路径 | |:---:|:---| | 修改 | [`MachineTaskDispatchCenter.java`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/core\/MachineTaskDispatchCenter.java) | | 新增 | `core/resourcechain/*`(Context、Outcome、Runner、handlers、Configuration) | | 新增 | `repository/machineTask/mapper/MachineTaskResourceWaitMapper.java` | | 新增 | `repository/machineTask/service/IMachineTaskResourceWaitService.java` + `impl/...` | | 复用实体 | [`MachineTaskResourceWait.java`](\/Users\/kazusa\/IdeaProjects\/baoshi\/wms\/baoshi-robot\/baoshi-robot-core\/src\/main\/java\/com\/baoshi\/robot\/repository\/machineTask\/entity\/MachineTaskResourceWait.java) | ## 风险与约定 - **行为回归**:必须以「与原 `lockResource` 分支完全一致」为第一约束;拆分仅改变结构不改变业务判断。 - **等待表粒度**:首期按上表枚举映射;若与后续「按资源唤醒」语义不一致再扩展枚举或小调 `resource_code` 约定。 - **事务**:保持与现有 RPC/st 状态机一致的边界;若当前无事务包裹,persist 等待表也不强行开启新全局事务除非已有模式。