Condividi tramite


Orleans panoramica del ciclo di vita

Alcuni Orleans comportamenti sono sufficientemente complessi che richiedono l'avvio e l'arresto ordinati. I componenti con tali comportamenti includono grani, silo e client. Per risolvere questo problema, Orleans è stato introdotto un modello generale di ciclo di vita dei componenti. Questo modello è costituito da un ciclo di vita osservabile, responsabile della segnalazione delle fasi di avvio e arresto di un componente e degli osservatori del ciclo di vita, responsabili dell'esecuzione di operazioni di avvio o arresto in fasi specifiche.

Per altre informazioni, vedere Ciclo di vita granulare e ciclo di vita del silo.

Ciclo di vita osservabile

I componenti che richiedono l'avvio e l'arresto ordinati possono usare un ciclo di vita osservabile. Ciò consente ad altri componenti di osservare il ciclo di vita e ricevere notifiche quando viene raggiunta una fase specifica durante l'avvio o l'arresto.

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

La chiamata di abbonamento registra un osservatore per ricevere notifica quando viene raggiunta una fase durante l'avvio o l'arresto. Il nome dell'osservatore viene usato per la creazione di report. La fase indica in quale punto della sequenza di avvio/arresto l'osservatore riceve la notifica. Ogni fase del ciclo di vita è osservabile. Tutti gli osservatori ricevono una notifica quando la fase viene raggiunta durante l'avvio e l'arresto. Le fasi iniziano in ordine crescente e si arrestano in ordine decrescente. L'osservatore può annullare la sottoscrizione eliminando l'oggetto eliminabile restituito.

Osservatore del ciclo di vita

I componenti che devono partecipare al ciclo di vita di un altro componente devono fornire hook per i comportamenti di avvio e arresto e sottoscrivere una fase specifica di un ciclo di vita osservabile.

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

Sia ILifecycleObserver.OnStart che ILifecycleObserver.OnStop vengono chiamati quando viene raggiunta la fase prevista durante l'avvio o l'arresto.

Servizi pubblici

Per praticità, esistono funzioni helper per i modelli di utilizzo comuni del ciclo di vita.

Estensioni

Le funzioni di estensione sono disponibili per la sottoscrizione a un ciclo di vita osservabile che non richiede che il componente di sottoscrizione implementi ILifecycleObserver. Questi consentono invece ai componenti di passare espressioni lambda o funzioni membro da chiamare nelle fasi sottoscritte.

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

Funzioni di estensione simili consentono di usare argomenti di tipo generico anziché il nome dell'osservatore.

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

Partecipazione al ciclo di vita

Alcuni punti di estendibilità richiedono un modo per riconoscere quali componenti sono interessati a partecipare a un ciclo di vita. Un'interfaccia marcatore per i partecipanti del ciclo di vita serve a questo scopo. Altri dettagli sul suo utilizzo sono trattati durante l'esplorazione dei cicli di vita di silo e grano.

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

Esempio

Dai test del Orleans ciclo di vita, di seguito è riportato un esempio di componente che partecipa a un ciclo di vita osservabile in più fasi.

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