恢复

概述

问题如何持久化流程,以便在引擎发生故障时可以恢复、重启或回滚?

答案:由于一个流程是一组 原子 以及原子之间的关系,我们需要创建一个模型和相应的的信息,以便持久化正确数量的信息,从而在软件或硬件故障时保存、恢复和回滚流程。

为了允许恢复,TaskFlow 必须能够重新创建流程并重新连接原子之间的链接(以及原子->原子细节之间的链接等等),以便撤销这些原子或以正确的顺序恢复这些原子。TaskFlow 提供了一种模式,可以帮助自动化此过程(它禁止用户创建自己的策略来执行此操作)。

工厂

默认提供的方案是提供一个 工厂 函数,该函数将创建(或重新创建)您的工作流。可以在加载流程和相应的引擎时通过提供的 load_from_factory() 方法提供此函数。这个 工厂 函数预计是一个函数(或 staticmethod),可以重新导入(即具有一个可以通过 Python 中的 __import__ 函数定位的明确名称,这排除了 lambda 风格的函数和 instance 方法)。工厂 函数的名称将被保存到日志簿中,并且将被导入和调用以创建工作流对象(或者在发生恢复时重新创建它)。这允许在需要时重新创建流程(即使在远程机器上,只要可以定位可重新导入的名称)。

名称

当创建流程时,预计每个原子都具有唯一的名称,此名称在恢复过程中具有特殊用途(同时在运行时也具有有用的用途,允许在 通知 过程中识别原子)。拥有名称的原因是流程中的原子需要在某种程度上与引擎恢复和后续运行期间的(可能)现有 AtomDetail 匹配。

匹配应该

  • 在添加或删除原子时保持稳定

  • 在服务重启、升级等情况下不应更改

  • 在 HA 设置中的所有服务器实例上应相同

名称提供了这一点,尽管它们确实存在弱点

  • 流程中原子的名称必须是唯一的

  • 更改原子名称变得困难,因为名称更改会导致其他副作用

注意

尽管存在这些弱点,名称仍被选为满足上述匹配要求的足够好的解决方案(直到发明/创建能够满足相同要求的更好方法)。

场景

当将新流程加载到引擎中时,尚未为其持久化数据,因此将创建一个相应的 FlowDetail 对象,以及包含在其中的每个原子都将创建一个 AtomDetail 对象。这些将立即保存到配置的持久化后端中。如果未配置持久化后端,那么如预期的那样,将不会保存任何内容,并且原子和流程将以非持久化方式运行。

后续运行: 当我们从持久化后端恢复流程时(例如,如果流程中断并且引擎被销毁以节省资源,或者服务被重启),我们需要重新创建流程。为此,我们将调用在第一次加载时保存的构建流程的函数(即,上面描述的流程工厂函数),然后引擎将运行。以下场景解释了一些预期的结构更改以及如何容纳它们(以及在恢复和运行时的影响)。

相同的原子

当上述工厂函数返回完全相同的流程和原子时(未进行任何更改)。

运行时更改: 不应执行任何操作 - 引擎将通过名称将原子与 AtomDetail 对象重新关联,然后引擎恢复。

添加了原子

当上述工厂函数通过添加新原子来更改流程时(例如,为了更改先前运行的结构的运行时结构)。

运行时更改: 默认情况下,当引擎恢复时,它会注意到没有相应的 AtomDetail 存在,并且将创建一个并关联。

删除了原子

当上述工厂函数通过删除新原子来更改流程时(例如,为了更改先前运行的结构的运行时结构)。

运行时更改: 不应执行任何操作 - 流程结构从工厂函数重新加载,并且删除的原子不在其中 - 因此,流程将像它不存在一样运行,并且在完成之前返回的任何结果都将被忽略。

原子代码已更改

当上述工厂函数通过决定运行较新版本的先前存在的原子来更改流程时(可能为了执行某种升级或修复先前原子代码中的错误)。

工厂更改: 原子名称和版本必须更改。工厂应替换先前使用过的此名称。

运行时更改: 这将属于与添加新原子相同的运行时调整。在未来,TaskFlow 可以通过提供一个 upgrade() 函数来简化此操作,该函数可用于为用户提供升级原子后再运行的能力(在引擎加载和运行之前可以对 LogBook 进行手动内省和修改,以同时完成此操作)。

原子被拆分为两个原子或合并

当上述工厂函数通过决定先前存在的原子应拆分为 N 个原子或工厂函数决定 N 个原子应合并为 <N 个原子时更改流程(通常发生在重构期间)。

运行时更改: 这将属于与添加或删除新原子相同的运行时调整。在未来,TaskFlow 可以通过提供一个 migrate() 函数来简化此操作,该函数可用于为用户提供迁移原子先前数据后再运行的能力(在引擎加载和运行之前可以对 LogBook 进行手动内省和修改,以同时完成此操作)。

流程结构已更改

如果手动添加或删除了图形中的链接,或者任务要求已更改,或者流程已重构(原子移动到子流程中或移出子流程,线性流程被替换为图形流程,线性流程中的任务已重新排序等)。

运行时更改: 不应执行任何操作。