4. 批次控制状态模型
在批次控制系统中,状态管理不是简单地记录“运行中”或“已完成”,而是要在多个层级上同时维护可观测、可追溯、可恢复的状态信息。作业级、步骤级、批次级三层状态模型,正是为了解决“同一时刻不同粒度状态不一致”这一核心问题而设计的。理解这三层状态的划分依据与聚合关系,是后续异常恢复、断点续跑和批次追溯的基础。
一、核心原理:为什么需要三层状态
批次控制的对象天然具有嵌套结构:一个批次包含若干作业,一个作业包含若干步骤。如果只维护一个全局状态,当异常发生时,系统无法判断是“整个批次失败”还是“某个步骤失败但作业仍可继续”。因此需要按粒度分层:
- 步骤级状态:描述单个工艺步骤的执行阶段,是最细粒度的状态,直接对应设备动作、参数设定和信号采集。
- 作业级状态:描述一个作业内所有步骤的整体推进情况,是步骤状态的聚合结果,决定作业能否继续、暂停或回退。
- 批次级状态:描述整个批次的生命周期阶段,是作业状态的聚合结果,面向生产调度、质量放行和批次追溯。
三层状态之间不是简单的“父子包含”,而是存在明确的聚合规则:下层状态向上层汇聚,上层状态向下层下发控制指令。聚合规则决定了当某个步骤异常时,作业和批次应呈现什么状态。
关键原则:状态聚合必须遵循“最严重优先”与“未完成不提升”两条规则。即下层存在异常时,上层不能显示为正常;下层未全部完成时,上层不能进入完成态。
二、状态划分与聚合关系
下面用一张状态聚合关系图展示三层状态之间的映射与汇聚路径。图中左侧为步骤级状态,中间为作业级状态,右侧为批次级状态,箭头表示聚合方向。
从图中可以看出,步骤级状态通过聚合规则映射为作业级状态,作业级状态再聚合为批次级状态。正常路径用蓝色箭头表示,异常路径用橙色箭头表示,异常会沿聚合方向向上传播,但不会自动向下回写。
三、聚合规则与状态映射表
聚合不是简单的“取最大值”,而是需要根据业务语义定义映射规则。下表给出典型的聚合映射关系:
| 下层状态组合 | 上层聚合结果 | 说明 |
|---|---|---|
| 所有步骤 COMPLETE | 作业 DONE | 全部完成才提升为完成态 |
| 存在步骤 RUNNING | 作业 ACTIVE | 有活动步骤即视为执行中 |
| 存在步骤 HOLD,无 RUNNING | 作业 PAUSED | 保持态聚合为暂停 |
| 存在步骤 FAULT | 作业 ERROR | 故障优先,覆盖其他状态 |
| 存在步骤 ABORTED | 作业 CANCELLED | 中止聚合为取消 |
| 所有作业 DONE | 批次 COMPLETED | 批次完成需全部作业完成 |
| 存在作业 ERROR | 批次 FAULTED | 任一作业故障即批次故障 |
| 存在作业 PAUSED,无 ERROR | 批次 HOLDING | 挂起状态向上聚合 |
提示:聚合规则应在系统配置中显式定义,而不是硬编码在程序逻辑里。这样当工艺变更时,只需调整映射表即可,无需修改代码。
四、案例场景:异常恢复中的状态聚合
假设一个批次包含 3 个作业,每个作业包含 4 个步骤。运行过程中,作业 2 的第 3 个步骤发生 FAULT,其余步骤处于 COMPLETE 或 IDLE。此时状态聚合过程如下:
- 步骤级:作业 2 的步骤 3 标记为 FAULT,步骤 1、2 为 COMPLETE,步骤 4 为 IDLE。
- 作业级:作业 2 聚合为 ERROR;作业 1 为 DONE;作业 3 为 ACTIVE。
- 批次级:由于存在 ERROR 作业,批次聚合为 FAULTED。
恢复时,操作员需要先处理作业 2 的故障步骤,将其重置为 IDLE 或重新执行。此时作业 2 从 ERROR 回到 ACTIVE,批次从 FAULTED 回到 RUNNING。整个过程依赖状态聚合关系自动完成,无需手动修改批次状态。
# 状态聚合伪代码示例
def aggregate_job_state(step_states):
if any(s == "FAULT" for s in step_states):
return "ERROR"
if any(s == "ABORTED" for s in step_states):
return "CANCELLED"
if any(s == "RUNNING" for s in step_states):
return "ACTIVE"
if any(s == "HOLD" for s in step_states):
return "PAUSED"
if all(s == "COMPLETE" for s in step_states):
return "DONE"
return "PENDING"
def aggregate_batch_state(job_states):
if any(j == "ERROR" for j in job_states):
return "FAULTED"
if any(j == "CANCELLED" for j in job_states):
return "TERMINATED"
if any(j == "ACTIVE" for j in job_states):
return "RUNNING"
if any(j == "PAUSED" for j in job_states):
return "HOLDING"
if all(j == "DONE" for j in job_states):
return "COMPLETED"
return "CREATED"
五、常见误区与复盘
误区一:把批次状态直接等同于“最后一个作业的状态”。这会导致批次在部分作业完成时提前进入 COMPLETED,掩盖未完成作业。
误区二:异常恢复时只重置步骤状态,忘记触发上层聚合。结果是步骤已恢复,但作业和批次仍停留在 ERROR/FAULTED,造成“假故障”。
误区三:聚合规则中未定义“部分完成”的中间态。例如所有步骤既非全部 COMPLETE 也非全部 IDLE 时,作业状态应明确为 ACTIVE 或 PAUSED,而不是模糊的“未知”。
复盘时建议检查三点:聚合规则是否覆盖所有状态组合;异常传播路径是否与恢复路径对称;状态变更是否写入了审计日志。只有三层状态模型与聚合关系清晰一致,批次控制才能在异常发生后快速定位、准确恢复、完整追溯。