Обзор жизненного цикла зерна

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<TState>.State загружается из хранилища.IStorage.RecordExiststrue
  • Activate: этап, где 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> чтобы сообщить жизненному циклу вызвать его OnSetupState метод во время GrainLifecycleStage.SetupState этапа жизненного Grain.Participate цикла.

Компоненты, созданные во время строительства зерна, также могут принимать участие в жизненном цикле без добавления специальной логики зерна. Так как контекст зерна (IGrainContext), включая жизненный цикл зерна (IGrainContext.ObservableLifecycle), создается перед созданием зерна, любой компонент, внедренный в зерно контейнером, может участвовать в жизненном цикле зерна.

Компоненты, созданные во время строительства зерна, также могут принимать участие в жизненном цикле без добавления специальной логики зерна. Так как контекст активации зерна (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;
    }
}