Orleans:构建高性能分布式Actor服务
上QQ阅读APP看书,第一时间看更新

3.3.1 Grain的运行时管理

在Orleans中,Grain实例本身的生命周期管理实际上只包括4个阶段:

其中,在First和Last阶段只在Orleans运行分布式事务时使用,用以确保在事务运行时间内参与事务的Grain实例不被回收;SetupState阶段包含了Grain实例在初始化过程中需要通知运行的组件逻辑,包括:

1)调用ReadStateAsync方法读取Grain状态。

2)初始化日志状态持久化Grain(Jounaled Grain)所依赖的相关日志服务。

3)为参与分布式事务的Grain初始化事务状态资源。

4)在Grain实例上下文中添加分布式事务管理器并初始化事务运行所需的其他资源和组件。

Active阶段即为实际的Grain激活阶段,在此阶段注册了Grain实例本身的OnActivateAsync和OnDeactivateAsync方法,由此确保Grain实例的OnActivateAsync/OnDeactivateAsync方法能够在Orleans运行时激活/休眠阶段被调用。对于多集群日志一致性类型的Grain而言,在Active阶段前后还分别增加了PerActivate阶段和PostActivate阶段,以在Grain实例激活/休眠前后进行对应的日志一致性记录。

对于一次Grain实例的初始激活(即从虚拟状态转为实际运行状态)过程而言,除了Grain实例的初始化(即工作流程)之外,Orleans运行时还需要管理Grain实例注册与验证、空闲超时时间点刷新、实例注册失败回滚等运行时阶段,这些阶段并不由每个Grain实例的GrainLifecycleSubject管理,而是作为所有Grain实例激活逻辑的一部分由Orleans运行时进行管理。

应用程序的自定义逻辑也可以通过在Grain类型内部对Participate方法的重写注册到Grain-LifecycleSubject上并在该类型的每一个Grian实例的生命周期中被触发运行。例如,若需要在SetupState阶段后加入自定义的AfterSetupState方法,则可以将该Grain类型的Participate方法重写为:

实际上在GrainLifecycleSubject开始执行时,Grain实例本身已经通过构造函数创建,因此在Grain构造函数中初始化的所有组件都可以在GrainLifecycleSubject注册的方法中使用。由于Grain实例的激活上下文IGrainActivationContext(实际着包含Grain实例GrainLifecycleSubject对象)也在Grain Lifecycle开始前被初始化完成,因此任何通过容器初始化并注入Grain实例的组件也可以在GrainLifecycleSubject注册的方法中使用。

虽然Grain实例的激活过程依赖于Grain Lifecycle,但由于Grain实例仍然会在某些异常情况下(如Silo异常退出)被强制休眠,因此应用程序在Grain休眠阶段所注册的逻辑将有可能被跳过。