Orleans 粒度使用可观察生命周期(请参阅 Orleans 生命周期)进行有序激活和停用。 这样,粒度逻辑、系统组件和应用程序逻辑就可以在粒度激活和收集期间以有序方式启动和停止。
阶段
预定义的粒度生命周期阶段如下所示:
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
:谷物生命周期中的第一阶段。 -
SetupState
:在激活之前设置粒度状态。 对于有状态的粒子,这是在IStorage.RecordExists为true
时从存储加载IStorage<TState>.State到Orleans的阶段。 -
Activate
:Orleans 调用 Grain.OnActivateAsync 和 Grain.OnDeactivateAsync. -
Last
:谷物生命周期中的最后一个阶段。
在粒子激活时使用粒子生命周期,但是在某些错误情况下(如存储器崩溃),粒子不会总是被停用。 因此,应用程序不应依赖于在粒度停用期间始终执行的粒度生命周期。
粮食生命周期参与
应用程序逻辑可以通过两种方式参与粒度的生命周期:
- 谷物可以参与其自己的生命周期。
- 组件可以通过粒度激活上下文访问生命周期(请参阅 IGrainContext.ObservableLifecycle)。
- 谷物可以参与其自己的生命周期。
- 组件可以通过粒度激活上下文访问生命周期(请参阅 IGrainActivationContext.ObservableLifecycle)。
粒度始终参与其生命周期,因此可以通过重写参与方法来引入应用程序逻辑。
参与示例
public override void Participate(IGrainLifecycle lifecycle)
{
base.Participate(lifecycle);
lifecycle.Subscribe(
this.GetType().FullName,
GrainLifecycleStage.SetupState,
OnSetupState);
}
在前面的示例中,Grain<TGrainState>重写Grain.Participate方法,以告知生命周期在其GrainLifecycleStage.SetupState阶段调用OnSetupState
方法。
在粒度构造期间创建的组件还可以参与生命周期,而无需添加任何特殊的粒度逻辑。 由于 Orleans 在创建粒度之前创建粒度上下文(IGrainContext包括其生命周期),IGrainContext.ObservableLifecycle因此容器注入粒度的任何组件都可以参与粒度的生命周期。
在粒度构造期间创建的组件还可以参与生命周期,而无需添加任何特殊的粒度逻辑。 由于 Orleans 在创建粒度之前创建粒度的激活上下文(IGrainActivationContext包括其生命周期),IGrainActivationContext.ObservableLifecycle因此容器注入粒度的任何组件都可以参与粒度的生命周期。
示例:组件参与
以下组件在使用其工厂函数Create(...)
创建时,会参与此“粒生命周期”。 此逻辑可能存在于组件的构造函数中,但这可能会在完全构造组件之前将组件添加到生命周期,这可能不安全。
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(...)
中注册示例组件,使用组件作为依赖项构造的任何粒度都使组件参与其生命周期,而无需在粒度本身中使用任何特殊逻辑。
在容器中注册组件
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());
以组件为依赖项的粒度
public class MyGrain : Grain, IMyGrain
{
private readonly MyComponent _component;
public MyGrain(MyComponent component)
{
_component = component;
}
}