发布时间:2023-10-30 浏览人数:1人查看
我们一直认为 MES/EAP 进入下一个阶段的分水岭,应该是 Brooks 提出 FactoryWork/StationWork 2.X 的时候。在那之前,MES 是终端式 Curses 风格(用过 Curses 程式库的应该都知天命了),EAP 则是 GW/SDR 作为主流。FactoryWork/StationWork 带领大家进入了另外一个世界,以 CellWork 作为中间件(MessageBus),服务(Services)和事件驱动(Event Driven),改变了所有人开发的方法,搭配上当年最火红的 VB6,成为了主流。
我们最近发现,还有人的 EAP 依然沿用 Station Work 的大部分设计,因为 C# 代码中出现了:
public EMLibrary(ref COEAPData xData, WriteToScreenFuncDele xFunc, ref VB6.Collection colInterface)
VB6.Collection ? .NET 的 Collection 不用,要用20年前的库 ?
使用场景(Scenario)/工作流(WorkFlow)
使用场景(Scenario)/工作流(WorkFlow)的做法最简单直接粗暴,一根肠子直接通到底,考虑以下的场景:
WorkFlow1 {
WaitForCarrierArrived
CheckMaterialCondition
TrackIn
DownloadAndSelectRecipe
EquipmentStart
WaitForDataCollection
DoDataCollection
WaitForCarrierCompleted
TrackOut
}
最大的问题就是,要有一个线程/程序来一直等着,如果系统写得不好,就牺牲了“负载均衡”和“冗余容错”。好处是简单直观,不容易出错,系统成本低。
事件驱动(Event Driven)
而事件驱动(Event Driven) 的写法如下:
WaitForCarrierArrived {
CheckCurrentState
CheckMaterialCondition
TrackIn
DownloadAndSelectRecipe
EquipmentStart
}
WaitForDataCollection {
CheckCurrentState
DoDataCollection
}
WaitForCarrierCompleted {
CheckCurrentState
TrackOut
}
每一个事件都会触发单一代码,每一个代码中都要检查是不是在对的状态,才能做对的事。例如在没有收到 WaitForCarrierArrived,这时候就必须要检查是不是在对的状态,才能做 DoDataCollection,而 Scenario/WorkFlow 则会直接跳过。
事件驱动(Event Driven)方式的最大缺点就是开发不人性化,开发人员根本无法直观的知道下一步要做什么,在执行上,由于不确定是哪一个服务(负载均衡)执行,所以要除错,要开一堆的日志(或是用 Elastic 类的工具)。但最大的好处就是“负载均衡”和“冗余容错”。
事件驱动(EventDriven)用互联网程序员懂的话说就是 Node.js 的方式。
我们在设计系统的时候,不论是 EAP 或是 MES,其实都需要兼容两种方式。而大部分传统的半导体 MES/EAP 主要支持的是事件驱动(Event Driven)的方式(例如 FactoryWork/StationWork),这个时候 TAG 就异常的重要了,如何把上一个事件(Event)执行的结果储存在 TAG 中,让下一个事件(Event)发生时知道上一个状态的结果。这个 TAG 的设计,应该是从 WinSecs 的 Transaction 中开始的 (至少在我经验中)。
不管是使用场景(Scenario)/工作流(WorkFlow)或是事件驱动(Event Driven)最关键的就是如何保证 “事件” 的顺序,通常大部分的 MES 都会加入一个队列(Queue)来保证事件的顺序。近年来,厂商都转向开源的队列,这样保护了客户的权益,而不是在未来变成孤儿(当然有些厂商依然用自己写的队列,在稳定性和未来维护性,我做为客户,我会有所担心)。
总而言之,没有对或错的设计,或是哪一种方式比较好,主要看哪一种方式最适合客户的场景。