Ü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;
}
First
: Erste Phase im Grain-LebenszyklusSetupState
: Eingerichteter Grain-Status vor der Aktivierung. Bei zustandsbehafteten Grains ist dies die Phase, in der IStorage<TState>.State aus dem Speicher geladen wird, wenn IStorage.RecordExists gleichtrue
ist.Activate
: Phase, in der Grain.OnActivateAsync und Grain.OnDeactivateAsync aufgerufen werdenLast
: Letzte Phase im Grain-Lebenszyklus
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).
- Das Grain kann an seinem Lebenszyklus teilnehmen.
- Komponenten können über den Grain-Aktivierungskontext auf den Lebenszyklus zugreifen (siehe IGrainActivationContext.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;
}
}