Vue d’ensemble du cycle de vie d’Orleans

Certains comportements d’Orleans sont suffisamment complexes pour nécessiter un démarrage et un arrêt ordonnés. Entre autres, les grains, les silos et les clients sont des composants présentant de tels comportements. Pour résoudre ce problème, un modèle de cycle de vie de composant général a été introduit. Ce modèle se compose d’un cycle de vie observable, qui est responsable de la signalisation dans les phases du démarrage et de l’arrêt d’un composant, et des observateurs de cycle de vie chargés d’effectuer les opérations de démarrage et d’arrêt dans les phases spécifiques.

Pour plus d’informations, consultez Cycle de vie des grains et Cycle de vie des silos.

Cycle de vie observable

Les composants qui ont besoin d’un démarrage et d’un arrêt ordonnés peuvent utiliser un cycle de vie observable qui permet à d’autres composants d’observer le cycle de vie et de recevoir une notification quand une phase est atteinte durant le démarrage ou l’arrêt.

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

L’appel d’abonnement inscrit un observateur aux notifications quand une phase est atteinte durant le démarrage ou l’arrêt. Le nom de l’observateur est utilisé à des fins de création de rapports. La phase indique à quel point dans la séquence de démarrage/d’arrêt l’observateur sera averti. Chaque phase du cycle de vie est observable. Tous les observateurs sont avertis quand la phase est atteinte durant le démarrage ou l’arrêt. Les phases sont démarrées dans l’ordre croissant et arrêtées dans l’ordre décroissant. L’observateur peut se désabonner en supprimant l’élément supprimable retourné.

Observateur de cycle de vie

Les composants qui doivent participer au cycle de vie d’un autre composant doivent fournir des hooks pour leurs comportements de démarrage et d’arrêt, et s’abonner à une phase spécifique d’un cycle de vie observable.

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

À la fois ILifecycleObserver.OnStart et ILifecycleObserver.OnStop sont appelés quand la phase ayant fait l’objet d’un abonnement est atteinte durant le démarrage/l’arrêt.

Services

Pour des raisons pratiques, les fonctions d’assistance ont été créées pour les modèles d’utilisation courants du cycle de vie.

Extensions

Les fonctions d’extension existent pour s’abonner à un cycle de vie observable, ce qui ne nécessite pas que le composant d’abonnement implémente ILifecycleObserver. Au lieu de cela, elles permettent aux composants de transmettre les fonctions lambda ou la fonction members à appeler dans les phases ayant fait l’objet d’un abonnement.

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

Des fonctions d’extension similaires permettent d’utiliser des arguments de type générique à la place du nom de l’observateur.

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

Participation au cycle de vie

Certains points d’extensibilité ont besoin d’un moyen de reconnaître les composants qui sont intéressés par une participation à un cycle de vie. Une interface de marqueur de participant au cycle de vie a été introduite à cet effet. Plus d’informations sur la façon de l’utiliser seront fournies dans le cadre de l’exploration des cycles de vie des silos et des grains.

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

Exemple

À partir de nos tests de cycle de vie, vous trouverez ci-dessous un exemple de composant participant à un cycle de vie observable dans plusieurs phases du cycle de vie.

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