Sdílet prostřednictvím


Přehled životního cyklu zrna

Orleans zrna používají pozorovatelný životní cyklus (viz Orleans životní cyklus) pro objednanou aktivaci a deaktivaci. To umožňuje jemné logice, systémovým komponentám a aplikační logice se spouštět a zastavovat uspořádaným způsobem během aktivace a sběru.

Stupně

Předdefinované fáze životního cyklu zrnitosti jsou následující:

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

I když Orleans používá životní cyklus zrnitosti během aktivace zrn, v některých chybových situacích, jako je například selhání sil, nemusí být zrní vždy deaktivováno. Proto by se aplikace neměly spoléhat na to, že životní cyklus jednotky bude vždy spuštěn během deaktivace jednotky.

Účast v životním cyklu obilí

Logika aplikace se může účastnit životního cyklu zrna dvěma způsoby:

  • Zrno se může účastnit svého vlastního životního cyklu.
  • Komponenty mají přístup k životnímu cyklu prostřednictvím kontextu aktivace "grain" (viz IGrainContext.ObservableLifecycle).

Zrno se vždy účastní se svého životního cyklu, takže logiku aplikace lze zavést tím, že se přepíše metoda účasti.

Příklad účasti

public override void Participate(IGrainLifecycle lifecycle)
{
    base.Participate(lifecycle);
    lifecycle.Subscribe(
        this.GetType().FullName,
        GrainLifecycleStage.SetupState,
        OnSetupState);
}

V předchozím příkladu přepíše metodu Grain<TGrainState> tak, aby řekl životnímu cyklu, Grain.Participate aby volal jeho OnSetupState metodu během GrainLifecycleStage.SetupState fáze životního cyklu.

Komponenty vytvořené během sestavování zrní se také mohou účastnit životního cyklu bez přidání speciální logiky zrnitosti. Vzhledem k tomu, že Orleans vytváří kontext zrna (IGrainContextvčetně jeho životního cykluIGrainContext.ObservableLifecycle), může se jakákoli komponenta vložená do zrna kontejnerem podílet na životním cyklu zrna.

Komponenty vytvořené během sestavování zrní se také mohou účastnit životního cyklu bez přidání speciální logiky zrnitosti. Vzhledem k tomu, že Orleans vytvoří kontext aktivace zrní (IGrainActivationContextvčetně jeho životního cykluIGrainActivationContext.ObservableLifecycle) před vytvořením zrní, mohou se do životního cyklu zrna zapojit všechny komponenty vložené do zrna kontejneru.

Příklad: Účast komponenty

Následující komponenta se účastní životního cyklu zrna, když je vytvářena pomocí tovární funkce Create(...). Tato logika by mohla existovat v konstruktoru komponenty, ale to by znamenalo riziko přidání komponenty do životního cyklu před jejím úplným sestavením, což nemusí být bezpečné.

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

Registrací ukázkové komponenty v kontejneru služby pomocí její funkce továrny se každé zrno, které má tuto komponentu jako závislost, účastní jejího životního cyklu, aniž by vyžadovalo jakoukoli zvláštní logiku v samotném zrnu.

Registrace komponenty v kontejneru

services.AddTransient<MyComponent>(sp =>
    MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
    MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());

Granule s komponentou jako závislostí

public class MyGrain : Grain, IMyGrain
{
    private readonly MyComponent _component;

    public MyGrain(MyComponent component)
    {
        _component = component;
    }
}