Udostępnij przez


Przegląd cyklu życia ziarna

Orleans ziarna używają obserwowanego cyklu życia (zobacz Orleans Cykl życia) do uporządkowanej aktywacji i dezaktywacji. Dzięki temu logika ziarna, składniki systemowe i logika aplikacji mogą być uruchamiane i zatrzymywane w uporządkowany sposób podczas aktywacji i zbierania ziarna.

Etapach

Wstępnie zdefiniowane etapy cyklu życia ziarna są następujące:

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

Chociaż Orleans używa cyklu życia ziarna podczas aktywacji ziarna, ziarna nie zawsze są dezaktywowane podczas niektórych przypadków błędów (takich jak awarie silosu). W związku z tym aplikacje nie powinny polegać na cyklu życia ziarna zawsze wykonywanym podczas dezaktywacji ziarna.

Udział w cyklu życia ziarna

Logika aplikacji może uczestniczyć w cyklu życia ziarna na dwa sposoby:

  • Ziarno może uczestniczyć we własnym cyklu życia.
  • Składniki mogą uzyskiwać dostęp do cyklu życia za pośrednictwem kontekstu aktywacji ziarna (zobacz IGrainContext.ObservableLifecycle).

Ziarno zawsze uczestniczy w jego cyklu życia, więc logikę aplikacji można wprowadzić przez przesłonięcie metody participate.

Przykładowe uczestnictwo

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

W poprzednim przykładzie Grain<TGrainState> zastępuje metodę Grain.Participate, aby zakomunikować cyklowi życia, że ma wywołać jej metodę OnSetupState na etapie GrainLifecycleStage.SetupState cyklu życia.

Składniki utworzone podczas budowy ziarna mogą również uczestniczyć w cyklu życia bez dodawania specjalnej logiki ziarna. Ponieważ Orleans tworzy kontekst ziarna (IGrainContext), w tym jego cykl życia (IGrainContext.ObservableLifecycle), przed utworzeniem ziarna, każdy składnik wstrzykiwany do ziarna przez kontener może uczestniczyć w cyklu życia ziarna.

Składniki utworzone podczas budowy ziarna mogą również uczestniczyć w cyklu życia bez dodawania specjalnej logiki ziarna. Ponieważ Orleans tworzy kontekst aktywacji ziarna (), w tym jego cykl życia (IGrainActivationContextIGrainActivationContext.ObservableLifecycle), przed utworzeniem ziarna, każdy składnik wstrzykiwany do ziarna przez kontener może uczestniczyć w cyklu życia ziarna.

Przykład: udział komponentów

Poniższy składnik uczestniczy w cyklu życia ziarna podczas tworzenia przy użyciu funkcji Create(...)fabryki . Ta logika może istnieć w konstruktorze składnika, ale wiąże się to z ryzykiem dodania składnika do cyklu życia przed jego w pełni skonstruowaniem, co może nie być bezpieczne.

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

Rejestrując składnik przykładowy w kontenerze usługi za pomocą funkcji fabryki, każde grono skonstruowane ze składnikiem jako zależnością, pozwala składnikowi uczestniczyć w jego cyklu życia bez potrzeby wprowadzania specjalnej logiki w samym gronie.

Zarejestruj składnik w kontenerze

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

Ziarno ze składnikiem jako zależność

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

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