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;
}

虽然 grain 生命周期将在 grain 激活期间使用,但由于 grain 在某些错误情况(例如 silo 崩溃)下不一定会被停用,因此应用程序不应指望 grain 生命周期总是会在 grain 停用期间执行。

Grain 生命周期参与

应用程序逻辑可以通过两种方式参与 grain 生命周期:

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;
    }
}