Introducción al ciclo de vida de Orleans

Algunos comportamientos de Orleans son tan complejos que necesitan un inicio y un apagado ordenados. Algunos componentes con estos comportamientos incluyen granos, silos y clientes. Para resolverlo, se ha introducido un patrón de ciclo de vida de componentes general. Este patrón consta de un ciclo de vida observable, que es responsable de la señalización en fases de inicio y apagado de un componente, y observadores del ciclo de vida que son responsables de realizar operaciones de inicio o apagado en fases específicas.

Para obtener más información, consulte Ciclo de vida de grano y Ciclo de vida de silo.

Ciclo de vida observable

Los componentes que necesitan el inicio y apagado ordenados pueden usar un ciclo de vida observable que permite a otros componentes observar el ciclo de vida y recibir una notificación cuando se alcanza una fase durante el inicio o apagado.

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

La llamada de suscripción registra un observador para recibir notificaciones cuando se alcanza una fase mientras se inicia o se detiene. El nombre del observador es con fines informativos. La fase indicada en qué punto de la secuencia de inicio y apagado se notificará al observador. Cada fase del ciclo de vida es observable. Se notificará a todos los observadores cuando se alcance la fase cuando se inicie y detenga. Las fases se inician en orden ascendente y se detienen en orden descendente. El observador puede cancelar la suscripción eliminando el descartable devuelto.

Observador del ciclo de vida

Los componentes que necesitan participar en el ciclo de vida de otro componente deben proporcionar enlaces para sus comportamientos de inicio y apagado y suscribirse a una fase específica de un ciclo de vida observable.

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

Se llama a ILifecycleObserver.OnStart y ILifecycleObserver.OnStop cuando se alcanza la fase suscrita a durante el inicio o apagado.

Sectores públicos

Para mayor comodidad, se han creado funciones auxiliares para patrones comunes de uso del ciclo de vida.

Extensiones

Existen funciones de extensión para suscribirse al ciclo de vida observable que no requiere que el componente de suscripción implemente ILifecycleObserver. En su lugar, estos permiten que los componentes pasen lambdas o funciones de miembros a las que se llamará en las fases suscritas.

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

Las funciones de extensión similares permiten usar argumentos de tipo genérico en lugar del nombre del observador.

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

Participación del ciclo de vida del silo

Algunos puntos de extensibilidad necesitan una manera de reconocer qué componentes están interesados en participar en un ciclo de vida. Se ha introducido una interfaz de marcador de participante del ciclo de vida para este fin. Más información sobre cómo se usa se tratará al explorar los ciclos de vida de silo y de grano.

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

Ejemplo

A partir de nuestras pruebas de ciclo de vida, a continuación se muestra un ejemplo de un componente que participa en un ciclo de vida observable en varias fases del ciclo de vida.

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