4. 批次控制状态模型

在批次控制系统中,状态管理不是简单地记录“运行中”或“已完成”,而是要在多个层级上同时维护可观测、可追溯、可恢复的状态信息。作业级、步骤级、批次级三层状态模型,正是为了解决“同一时刻不同粒度状态不一致”这一核心问题而设计的。理解这三层状态的划分依据与聚合关系,是后续异常恢复、断点续跑和批次追溯的基础。

一、核心原理:为什么需要三层状态

批次控制的对象天然具有嵌套结构:一个批次包含若干作业,一个作业包含若干步骤。如果只维护一个全局状态,当异常发生时,系统无法判断是“整个批次失败”还是“某个步骤失败但作业仍可继续”。因此需要按粒度分层:

  • 步骤级状态:描述单个工艺步骤的执行阶段,是最细粒度的状态,直接对应设备动作、参数设定和信号采集。
  • 作业级状态:描述一个作业内所有步骤的整体推进情况,是步骤状态的聚合结果,决定作业能否继续、暂停或回退。
  • 批次级状态:描述整个批次的生命周期阶段,是作业状态的聚合结果,面向生产调度、质量放行和批次追溯。

三层状态之间不是简单的“父子包含”,而是存在明确的聚合规则:下层状态向上层汇聚,上层状态向下层下发控制指令。聚合规则决定了当某个步骤异常时,作业和批次应呈现什么状态。

关键原则:状态聚合必须遵循“最严重优先”与“未完成不提升”两条规则。即下层存在异常时,上层不能显示为正常;下层未全部完成时,上层不能进入完成态。

二、状态划分与聚合关系

下面用一张状态聚合关系图展示三层状态之间的映射与汇聚路径。图中左侧为步骤级状态,中间为作业级状态,右侧为批次级状态,箭头表示聚合方向。

批次控制三层状态聚合关系 步骤级状态 Step State IDLE 空闲 RUNNING 执行中 HOLD 保持 COMPLETE 完成 FAULT 故障 ABORTED 中止 作业级状态 Job State PENDING 待执行 ACTIVE 执行中 PAUSED 暂停 DONE 已完成 ERROR 异常 CANCELLED 取消 批次级状态 Batch State CREATED 已创建 RUNNING 生产中 HOLDING 挂起 COMPLETED 完成 FAULTED 故障 TERMINATED 终止 聚合 聚合 异常传播 异常传播

从图中可以看出,步骤级状态通过聚合规则映射为作业级状态,作业级状态再聚合为批次级状态。正常路径用蓝色箭头表示,异常路径用橙色箭头表示,异常会沿聚合方向向上传播,但不会自动向下回写。

三、聚合规则与状态映射表

聚合不是简单的“取最大值”,而是需要根据业务语义定义映射规则。下表给出典型的聚合映射关系:

下层状态组合 上层聚合结果 说明
所有步骤 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。此时状态聚合过程如下:

  1. 步骤级:作业 2 的步骤 3 标记为 FAULT,步骤 1、2 为 COMPLETE,步骤 4 为 IDLE。
  2. 作业级:作业 2 聚合为 ERROR;作业 1 为 DONE;作业 3 为 ACTIVE。
  3. 批次级:由于存在 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,而不是模糊的“未知”。

复盘时建议检查三点:聚合规则是否覆盖所有状态组合;异常传播路径是否与恢复路径对称;状态变更是否写入了审计日志。只有三层状态模型与聚合关系清晰一致,批次控制才能在异常发生后快速定位、准确恢复、完整追溯。