LMES 流程引擎
摘要
本文档详细介绍了LMES流程引擎的原理、配置方法和应用场景。LMES流程引擎是工作流在产线MES领域的特定应用和深化拓展,专为满足产线复杂的自动化流程管理需求而设计。文档适合系统管理员、开发人员和业务分析师阅读,帮助理解和使用LMES流程引擎。
1、原理
什么是流程引擎?顾名思义,是支持流程编排,流程执行的引擎底座。在低代码平台、办公自动化(OA)、BPM平台、工作流系统均需要流程引擎功能。其解决的问题主要为复杂流程中状态的灵活管理以及可编排性。
LMES 流程引擎是工作流在产线 MES 领域的一种特定应用和深化拓展,它在功能、应用场景和设计目标上与一般的工作流有所不同,更具专业性和针对 性,以满足产线复杂的自动化流程管理需求。
以下分别从静态的角度,了解组成LMES流程引擎的要素,以及这些要素如何被组织成流程定义,然后才能从动态的角度,了解流程引擎的工作原理。
1.1、静态模型:流程定义
流程定义由一系列基本的处理活动按照一定的逻辑顺序规则组成,从抽象的角度,流程可以映射成步骤和迁移连接组成的有向图,而流转数据则是运行时搭载在流程上的数据和信息。下面分别描述这三个组成要素。
1.1.1、活动(Activity)
在流程引擎中,活动(Activity) 是构成业务流程的基本单元,代表流程中的一个具体操作或步骤。在自动化业务流程引擎中:Activity 翻译为"步骤" 是一个不错的选择。因为这类引擎重点关注系统自动执行的各种操作,"Activity" 通常对应着具体的系统操作步骤,如数据查询、文件传输、指令发送等,"步骤" 能准确传达其在自动化流程中的功能和动作。
步骤往往携带相关的属性,属性包括名称、描述、运行方式、标识等内置属性,还包括不同步骤类型包含的扩展信息,譬如,人工参与步骤,则需要存放人员/角色等相关信息,可扩展性步骤,包 含有用户自定义的脚本 Script 属性。步骤是可扩展、可定义、可组合、可重用的。另外,
每个步骤还有迁入/迁出的属性信息。
1.1.1.1、步骤类型
- 步骤从运行的角度上分,可以分为自动执行和人工参与,譬如,"自动执行步骤" 指的是流程在运行过程中,无需人工手动干预,系统按照预先设定的规则和逻辑自动进行的操作环节。"人工参与步骤"是指通过任务通知用户,依靠人工手动启动应用,完成相应的功能(比如审批流程里的,用户选择 通过,拒绝)。
- 从规模角度上分,可以分为原子步骤和混合步骤,原子步骤是内置不可被分解的操作步骤,譬如:开始步骤、结束步骤,混合步骤是多个原子步骤的组合。
- 从类型上分,可以有开始步骤、结束步骤、启动子流程步骤等预定义步骤,也可以是通过.NET 脚本定义的可扩展步骤。
1.1.1.2、步骤名称
步骤名称:是指该步骤的唯一标识,在整个流程定义文件中必须保持唯一。
1.1.1.3、进入/退出
每个步骤在运行时都会触发三个事件,分别是 OnEnter、OnExecute、OnExit 三个事件。
-
进入模式
有"手动"和"自动"两个选项,指示进入该步骤的方式。
如果该步骤的进入模式为"手动" ,则流程运行到该步骤时只会触发该步骤的 OnEnter 事件,然后会等待 用户处理这个步骤时(
Flow.RunAsync(ActivityName)) 才会触发 OnExecute 事件;如果该步骤的进入模式为"自动" ,则流程运行到该步骤时会触发该步骤的 OnEnter 和 OnExecute 方法。
-
退出模式
有"手动"和"自动"两个选项,指示退出该步骤的方式。
如果该步骤的退出模式为"手动" ,则流程运行到该步骤时只会触发该步骤的 OnExecute 事件,然后会等待用户处理这个步骤时(
Flow.RunAsync(ActivityName)) 才会触发 **OnExit ** 事件;如果该步骤的退出模式为"自动" ,则流程运行到该步骤时会触发该步骤的 OnExecute 和 OnExit 方法。
进入模式讨论的是从 OnEnter 到 OnExecute 的执行模式,而退出模式就是从OnExecute 到 OnExit 的模式。
注意: 当步骤是流程的启动步骤时,无论是手动还是自动,OnEnter 方法都不会执行。当步骤是结束步骤时,无论手动还是自动,OnExit 方法都不会行。

1.1.1.4、迁入/迁出
-
迁出模式
含义:描述的是步骤执行完成后,流程将如何继续流转,即该步骤的后置条件或出口条件。它定义了在当前步骤执行完毕后,根据不同的结果或条件,流程会前往哪些后续步骤。共有"SplitAND"和"SplitXOR"两个选项

SplitAND (与拆分):步骤的多个后继步骤,只要后续步骤的迁移条件成立,所有的后续步骤都会被触发。即 平行拆分(Parallel Split)表示流程中从一个线程中的一个点拆分为在多个线程中平行执行的多个活动。a的完成激活了b、c的同时执行。
SplitXOR (异或拆分):步骤的多个后继步骤,后续步骤的迁移条件都成立时,只触发第一个后续步骤。即Exclusive Choice 排他选择,意思就是工作流中的一个点,基于决定或者流程中的数据,流向若干个分支中的一个。 a的完成只能激活b、c的其中一个执行。
-
迁入模式
含义:描述的是一个步骤在何种条件下被触发进入,即该步骤的前置条件或入口条件。它定义了流程是如何到达当前步骤的,包括来自哪些其他步骤以及满足什么样的特定条件。共有"JoinAND"和"JoinXOR"两个选项

JoinAND (与合并):步骤的多个前驱步骤,必须所有的前驱步骤都完成,且迁移条件成立,该步骤才会被触发执行。即 同步(Synchronization),表示流程中的多个活动在一个点上汇合成一个线程。要求b、c都被完成,d才会被激活。
JoinXOR (异或合并):步骤的多个前驱步骤,只要有一个前驱步骤完成,且迁移条件成立,该步骤就会被触发执行。即 简单合并(Simple Merge),表示 d或c完成后,d即被激活,不要求b、c都完成。
1.1.2、迁移(Transition)
迁移代表从一个步骤(迁出步骤)切换到另一个步骤(迁入步骤),其中迁出步骤是迁入步骤的前趋步骤,迁入步骤是迁出步骤的后继步骤,迁移与条件结合通过判断迁移上的条件是否成立来完成迁移的过程。通过在迁移上面绑定不同的条件类型。
迁移又分为无条件迁移和条件迁移。条件迁移就是指在执行该迁移要满足一定的条件,如设置了某个表达式ok==true,只要该表达式为真就执行这个迁移,否则就不执行这个迁移。无条件迁移就是指一定会执行该迁移,不需要满足任何条件。
1.1.3、条件(Condition)
迁移成立的条件的基类。实现ICondition对条件的定义,迁移是联系环节与环节之间的纽带,每个迁移都必须有方向(单方向)。当环节与环节之间用迁移联系起来后,并不代表执行的时候,环节就能够从源环节跳转到目标环节上。因为每个迁移上还可以绑定迁移条件。只有在迁移条件成立了之后,迁移才能够真正的将两个环节联系起来。
1.1.3.2、属性条件(PropertyCondition)
如果业务数据绑定的是某个对象,这时候就可以使用对象属性条件来直接通过比较该对象的某一属性来判断条件是否成立。当条件的迁移与表单中的某个数据项有关时,就可以用属性条件作为迁移条件。需要特别强调的是:当使用了属性条件时,就要确保这个流程关联的对象里有这样一个属性,否则流程的运转可能会产生错误。
属性条件的 条件表达式掩码: {Parameter}.{Property} {Operator}{PropertyToCompare}
参数名(Parameter):流程上下文标识,即流程数据字典里的一个Key值,如果为空的话就引用ApplicationData参数。
属性名(Property): 如果该Key对应的数据为复杂类型,可通过 参数名.属性名 的方式进一步求值,当 属性名 为空时直接比较 属性名 获取的值。
比较符(Operator): 属性的判断操作。
需要比较的值(PropertyToCompare):如果比较同一个对象的属性可以直接设置属性名,如果需要比较流程参数里面另外一个对象的属性的话,就通过Parameter.Property的形式表达。
**常量值: **需要比较的值如果是常量 则可直接 填写 常量值, 否则使用 需要比较的值, 两者二选一。

1.1.3.3、复合条件(CompositeCondition)
复合条件可以看作为一个条件的容器,通过与和或的关系,组合不同的条件以实现复杂的条件计算。

1.2、动态模型:流程实例
1.2.1、流程实例(FlowInstance)
流程定义描述业务流程的执行情况,而流程实例是根据流程定义被真正运行起来的一个实例。流程实例处理包含程的一个定义副本 以及 流转数据。
从数学模型上看,流程实例的执行可被标记如下:
用有向图 M = {D,A,T}来表达流程程实例,其中:
D={d1,d2,„,dn}代表流转数据的集合
A={a1,a2,„,an}代表环节的集合
T={t1,t2,„,tn}代表迁移连接的集合, 其中 t1=(aj,ak)为从 aj 到 ak 的迁移, aj,ak∈A
约定:
∀ai,aj∈A,若有 t=(ai,aj)∈T,则 ai 是 aj 的前趋环节,aj 是 ai 的后继环节,t 是 ai 的一条输出迁移,t 是 aj 的一条输入迁移;
若有 A'⊆A,且 A'={a'|(a',a)∈T},则 A'为环节 a 的前趋环节集合;若有 A'⊆A,且A'={a'|(a,a')∈T},则 A'为环节 a 的后继环节集合;
若有 T'⊆T,且 T(a)'={t|t(a,a')∈T},则 T'为环节 a 的输出迁移集合;若有 T'⊆T,且T(a)'={t|t(a',a)∈T},则 T'为环节 a 的输入迁移集合;迁入/迁出集合,支持 XOR 或 AND 运算;
记状态函数
对于∀a∈A,有状态函数 state(a)={-1,0,1},当环节处在未执行状态下,state(a)=-1;当环节正在执行的时候,state(a)=1;当环节执行完毕,state(a)=0;初始状态,∀a∈A,state(a)=-1;
记迁移函数
对于∀t∈T,有迁移函数 tran(t)={-1,0,1}当 tran(t)=1,代表允许发生迁移;当 tran(t)=0,代表迁移不能发生;当 tran(t)=-1,代表了迁移现在还未能确定;对于迁入/迁出集合 T', 支持XOR/AND
存在流转规则如下:
∀a∈A,state(a)≠1, tran(T(a))=1,则 state(a)=1;当 state(a)=1,且执行完毕,state(a)=0;
∀t=(a,a')∈T,当 state(a)从 1 变成 0,若 tran(T(a'))=1,则发生转移,若 tran(T(a'))≠1,则不发生转移,直到下次 state(a)从 1 变成 0 才应用此规则
按照以上的数据描述构成了流程引擎的工作原理,流程引擎处理的流程实例根据其使用的流程定义在与第三方交互下或者系统自动触发下,不断检查满足触发条件的步骤,并且根据执行的情况。如果一个步骤执行完毕,则该步骤对应的状态被设置为 结束,从而触发流程引擎继续流转,直到遇到结束步骤。

1.2.2、流转数据(DataItems)
流转数据也可以称为 流程上下文 数据,流程上下文是流程引擎在执行流程时,用于存储和管理流程实例相关数据、状态、参数等信息的"虚拟容器",是支撑流程节点交互与逻辑推进的核心要素,按类型分内部数据和外部数据。
内部数据包括:
- 标准参数数据:如流程标识、流程实例标识等信息
- 流转运算相关的数据,包括流程运转过程的历史痕迹(日志)、流程当前的状态、各个步骤当前的状态
- 流转计算过程中的临时数据
外部数据包括:
- 运行时刻,搭载在流程实例上的数据,可以是文件,也可以是一条业务数据记录
- 运行时刻,触发该流程的工位配置数据
核心作用:
- 数据共享:实现不同节点间数据传递
- 逻辑驱动:作为流程分支、条件判断的依据
- 状态跟踪:记录流程运行轨迹,支持回溯、监控。例如,通过流程实例ID可查看流程经过的节点与处理记录

1.2.2、生命周期
流程实例的生命周期:指按照流程设定的环节和步骤、遵照流程的规则和规范实际运行的一个具体流程从开始到结束的过程。以下是一般情况下流程实例生命周期的不同阶段:
- 创建阶段:当一个具体的业务实例触发流程时,流程实例被创建。此时会为该实例分配唯一的标识符,系统会初始化相关的变量、数据结构等,为流程的后续执行做准备。例如,在工序业务流程中,流程服务启动后,系统就会为所有工位创建其关联的流程对应的流程实例。
- 运行阶段:流程实例按照预设的流程路径开始执行,依次经过各个环节和步骤。在这个过程中,可能会涉及到变量操作、数据的处理和传递等操作,每个环节都有相应的处理逻辑和操作。
- 等待阶段:在流程执行过程中,可能会因为某些条件不满足而进入等待状态。例如,在进站流程中,需要监听 "进站信号==1",此时流程实例会暂停执行,直到满足继续执行的条件。
- 完成阶段:当流程实例经过 结束步骤,这表示流程的一次具体执行过程 已结束,相关的业务处理也已完成。当然也存在一些没有明确结束步骤的流程,这类流程通常具有循环、持续运行或根据特定条件动态变化的特点。没有 结束步骤 的流程,永远都不会自动结束,除非流程抛异常,主动停止,程序退出。
- 异常处理阶段:在流程执行过程中,如果出现了错误、异常情况或违反了流程规则,就需要进行异常处理。这可能包括回滚操作、记录错误信息,重启流程等,以确保流程的正确性和数据的一致性。异常流程被自动标记为 已结束。
- 归档阶段:流程实例完成后,相关的执行日志会被归档保存,以便后续查询、审计和分析,流程实例上下文数据暂不做持久化处理。
- 销毁阶段: 当流程实例完成其任务并进入结束阶段时,需要将其所占用的内存空间释放出来,以便其他程序或流程实例可以使用这些资源。如果不及时释放内存,可能会导致系统内存泄漏,使可用内存逐渐减少,最终影响系统的性能甚至导致系统崩溃。
