Orleans przegląd cyklu życia

Niektóre Orleans zachowania są wystarczająco złożone, że wymagają uporządkowanego uruchamiania i zamykania. Niektóre składniki z takimi zachowaniami obejmują ziarna, silosy i klientów. Aby rozwiązać ten problem, wprowadzono ogólny wzorzec cyklu życia składników. Ten wzorzec składa się z zauważalnego cyklu życia, który jest odpowiedzialny za sygnalizowanie na etapach uruchamiania i zamykania składnika oraz obserwatorów cyklu życia odpowiedzialnych za wykonywanie operacji uruchamiania lub zamykania na określonych etapach.

Aby uzyskać więcej informacji, zobacz Cykl życia ziarna i Cykl życia silosu.

Obserwowany cykl życia

Składniki, które wymagają uporządkowanego uruchamiania i zamykania, mogą korzystać z zauważalnego cyklu życia, który umożliwia innym składnikom obserwowanie cyklu życia i otrzymywanie powiadomienia po osiągnięciu etapu podczas uruchamiania lub zamykania.

public interface ILifecycleObservable
{
    IDisposable Subscribe(
        string observerName,
        int stage,
        ILifecycleObserver observer);
}

Wywołanie subskrypcji rejestruje obserwatora w celu powiadomienia, gdy etap zostanie osiągnięty podczas uruchamiania lub zatrzymywania. Nazwa obserwatora służy do raportowania. Etap wskazany w którym momencie w sekwencji uruchamiania/zamykania obserwator zostanie powiadomiony. Każdy etap cyklu życia można zaobserwować. Wszyscy obserwatorzy zostaną powiadomieni o osiągnięciu etapu podczas uruchamiania i zatrzymywania. Etapy są uruchamiane w kolejności rosnącej i zatrzymywane w kolejności malejącej. Obserwator może anulować subskrypcję, dysponując zwrócone jednorazowe.

Obserwator cyklu życia

Składniki, które muszą wziąć udział w cyklu życia innego składnika, muszą zapewnić haki dla ich zachowań uruchamiania i zamykania oraz subskrybować określony etap obserwowanego cyklu życia.

public interface ILifecycleObserver
{
    Task OnStart(CancellationToken ct);
    Task OnStop(CancellationToken ct);
}

Zarówno ILifecycleObserver.OnStart , jak i ILifecycleObserver.OnStop są wywoływane, gdy etap subskrybowany jest podczas uruchamiania/zamykania.

Narzędzia

Dla wygody funkcje pomocnika zostały utworzone dla typowych wzorców użycia cyklu życia.

Rozszerzenia

Funkcje rozszerzeń istnieją do subskrybowania w celu obserwowanego cyklu życia, który nie wymaga implementowania subskrybowanego składnika ILifecycleObserver. Zamiast tego umożliwiają one składnikom przekazywanie funkcji lambda lub elementów członkowskich do wywoływanych na subskrybowanych etapach.

IDisposable Subscribe(
    this ILifecycleObservable observable,
    string observerName,
    int stage,
    Func<CancellationToken, Task> onStart,
    Func<CancellationToken, Task> onStop);

IDisposable Subscribe(
    this ILifecycleObservable observable,
    string observerName,
    int stage,
    Func<CancellationToken, Task> onStart);

Podobne funkcje rozszerzenia umożliwiają używanie argumentów typu ogólnego zamiast nazwy obserwatora.

IDisposable Subscribe<TObserver>(
    this ILifecycleObservable observable,
    int stage,
    Func<CancellationToken, Task> onStart,
    Func<CancellationToken, Task> onStop);

IDisposable Subscribe<TObserver>(
    this ILifecycleObservable observable,
    int stage,
    Func<CancellationToken, Task> onStart);

Uczestnictwo w cyklu życia

Niektóre punkty rozszerzalności wymagają sposobu rozpoznawania składników zainteresowanych udziałem w cyklu życia. W tym celu wprowadzono interfejs znacznika uczestnika cyklu życia. Więcej informacji o tym, jak ta funkcja będzie używana podczas eksplorowania cykli życia silosu i ziarna.

public interface ILifecycleParticipant<TLifecycleObservable>
    where TLifecycleObservable : ILifecycleObservable
{
    void Participate(TLifecycleObservable lifecycle);
}

Przykład

W naszych testach cyklu życia poniżej znajduje się przykład składnika, który bierze udział w obserwowanym cyklu życia na wielu etapach cyklu życia.

enum TestStages
{
    Down,
    Initialize,
    Configure,
    Run,
};

class MultiStageObserver : ILifecycleParticipant<ILifecycleObservable>
{
    public Dictionary<TestStages,bool> Started { get; } = new();
    public Dictionary<TestStages, bool> Stopped { get; } = new();

    private Task OnStartStage(TestStages stage)
    {
        Started[stage] = true;

        return Task.CompletedTask;
    }

    private Task OnStopStage(TestStages stage)
    {
        Stopped[stage] = true;

        return Task.CompletedTask;
    }

    public void Participate(ILifecycleObservable lifecycle)
    {
        lifecycle.Subscribe<MultiStageObserver>(
            (int)TestStages.Down,
            _ => OnStartStage(TestStages.Down),
            _ => OnStopStage(TestStages.Down));

        lifecycle.Subscribe<MultiStageObserver>(
            (int)TestStages.Initialize,
            _ => OnStartStage(TestStages.Initialize),
            _ => OnStopStage(TestStages.Initialize));

        lifecycle.Subscribe<MultiStageObserver>(
            (int)TestStages.Configure,
            _ => OnStartStage(TestStages.Configure),
            _ => OnStopStage(TestStages.Configure));

        lifecycle.Subscribe<MultiStageObserver>(
            (int)TestStages.Run,
            _ => OnStartStage(TestStages.Run),
            _ => OnStopStage(TestStages.Run));
    }
}