Grain 生命周期概述
Orleans grain 使用可观察的生命周期(请参阅 Orleans 生命周期)进行有序激活和停用。 这使 grain 逻辑、系统组件和应用程序逻辑能够在 grain 激活和收集期间以有序方式启动和停止。
阶段
预定义的 grain 生命周期阶段如下所示。
public static class GrainLifecycleStage
{
public const int First = int.MinValue;
public const int SetupState = 1_000;
public const int Activate = 2_000;
public const int Last = int.MaxValue;
}
First
:grain 生命周期中的第一阶段。SetupState
:在激活前设置 grain 状态。 对于有状态 grain,这是 IStorage.RecordExists 为true
时从存储加载 IStorage<TState>.State 的阶段。Activate
:Grain.OnActivateAsync 和 Grain.OnDeactivateAsync 被调用的阶段。Last
:grain 生命周期中的最后阶段。
虽然 grain 生命周期将在 grain 激活期间使用,但由于 grain 在某些错误情况(例如 silo 崩溃)下不一定会被停用,因此应用程序不应指望 grain 生命周期总是会在 grain 停用期间执行。
Grain 生命周期参与
应用程序逻辑可以通过两种方式参与 grain 生命周期:
- Grain 可以参与其生命周期。
- 组件可以通过 grain 激活上下文访问生命周期(请参阅 IGrainContext.ObservableLifecycle)。
- Grain 可以参与其生命周期。
- 组件可以通过 grain 激活上下文访问生命周期(请参阅 IGrainActivationContext.ObservableLifecycle)。
Grain 始终参与其生命周期,因此可以通过重写参与方法引入应用程序逻辑。
示例参与
public override void Participate(IGrainLifecycle lifecycle)
{
base.Participate(lifecycle);
lifecycle.Subscribe(
this.GetType().FullName,
GrainLifecycleStage.SetupState,
OnSetupState);
}
在上面的示例中,Grain<TGrainState> 重写 Grain.Participate 方法,以指示生命周期在生命周期的 GrainLifecycleStage.SetupState 阶段调用其 OnSetupState
方法。
在 grain 的构造期间创建的组件也可以参与生命周期,而无需添加任何特殊的 grain 逻辑。 由于 grain 的上下文 (IGrainContext)(包括 grain 的生命周期 (IGrainContext.ObservableLifecycle))是在创建 grain 之前创建的,因此,由容器注入到 grain 的任何组件都可以参与 grain 的生命周期。
在 grain 的构造期间创建的组件也可以参与生命周期,而无需添加任何特殊的 grain 逻辑。 由于 grain 的激活上下文 (IGrainActivationContext)(包括 grain 的生命周期 (IGrainActivationContext.ObservableLifecycle))是在创建 grain 之前创建的,因此,由容器注入到 grain 的任何组件都可以参与 grain 的生命周期。
示例参与、创建和激活
以下组件在通过其工厂函数 Create(...)
创建时,参与了 grain 的生命周期。 此逻辑可存在于组件的构造函数中,但这样一来,组件就有在被完全构造之前被添加到生命周期的风险,这可能不安全。
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainActivationContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
通过使用示例组件的 Create(...)
工厂函数在服务容器中注册该组件,在将该组件作为依赖项的情况下构造的任何 grain 都会让组件参与其生命周期,而 grain 中无需存在任何特殊逻辑。
在容器中注册组件
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());
将组件作为依赖项的 grain
public class MyGrain : Grain, IMyGrain
{
private readonly MyComponent _component;
public MyGrain(MyComponent component)
{
_component = component;
}
}