Übersicht über den Grain-Lebenszyklus

OrleansOrleans-Grains nutzen einen beobachtbaren Lebenszyklus (siehe Orleans Lifecycle (Übersicht über den Orleans-Lebenszyklus)) für die geordnete Aktivierung und Deaktivierung. Dadurch können Grain-Logik, Systemkomponenten und Anwendungslogik während der Aktivierung und Sammlung von Grains geordnet gestartet und beendet werden.

Phasen

Die vordefinierten Phasen des Grain-Lebenszyklus sind wie folgt:

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

Der Grain-Lifecycle wird zwar während der Grain-Aktivierung verwendet, aber da Grains in manchen Fehlerfällen (z. B. bei einem Siloabsturz) nicht immer deaktiviert werden, sollten sich Anwendungen nicht darauf verlassen, dass der Grain-Lebenszyklus bei der Deaktivierung von Grains immer ausgeführt wird.

Teilnahme am Grain-Lebenszyklus

Anwendungslogik kann auf zwei Arten am Lebenszyklus eines Grains teilnehmen:

  • Das Grain kann an seinem Lebenszyklus teilnehmen.
  • Komponenten können über den Grain-Aktivierungskontext auf den Lebenszyklus zugreifen (siehe IGrainContext.ObservableLifecycle).

Ein Grain nimmt immer an seinem Lebenszyklus teil. Anwendungslogik kann also eingeführt werden, indem die Teilnahmemethode überschrieben wird.

Beispielteilnahme

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

Im obigen Beispiel überschreibt Grain<TGrainState> die Grain.Participate-Methode, um den Lebenszyklus aufzufordern, seine OnSetupState-Methode während der Phase GrainLifecycleStage.SetupState des Lebenszyklus aufzurufen.

Komponenten, die während der Grain-Erstellung erstellt werden, können ebenfalls am Lebenszyklus teilnehmen, ohne dass eine spezielle Grain-Logik hinzugefügt wird. Da der Grain-Kontext (IGrainContext), einschließlich des Grain-Lebenszyklus (IGrainContext.ObservableLifecycle), erstellt wird, bevor das Grain erstellt wird, kann jede vom Container in das Grain eingefügte Komponente am Lebenszyklus des Grains teilnehmen.

Komponenten, die während der Grain-Erstellung erstellt werden, können ebenfalls am Lebenszyklus teilnehmen, ohne dass eine spezielle Grain-Logik hinzugefügt wird. Da der Grain-Aktivierungskontext (IGrainActivationContext), einschließlich des Grain-Lebenszyklus (IGrainActivationContext.ObservableLifecycle), erstellt wird, bevor das Grain erstellt wird, kann jede vom Container in das Grain eingefügte Komponente am Grain-Lebenszyklus teilnehmen.

Beispiel für Teilnahme, Erstellung und Aktivierung

Die folgende Komponente nimmt am Grain-Lebenszyklus teil, wenn sie mit ihrer Factoryfunktion Create(...) erstellt wird. Diese Logik kann im Konstruktor der Komponente enthalten sein. Dann besteht jedoch das Risiko, dass die Komponente dem Lebenszyklus hinzugefügt wird, bevor sie vollständig erstellt wurde. Dies ist möglicherweise nicht sicher.

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

Wenn Sie die Beispielkomponente im Dienstcontainer mithilfe der Factoryfunktion Create(...) registrieren, wird für jedes Grain, das mit der Komponente als Abhängigkeit erstellt wird, die Komponente an ihrem Lebenszyklus ohne spezielle Logik im Grain teilnehmen.

Registrieren der Komponente im Container

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

Grain mit Komponente als Abhängigkeit

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

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