Compartilhar via


Visão geral do ciclo de vida do Orleans

Alguns Orleans comportamentos são suficientemente complexos que exigem inicialização e desligamento ordenados. Os componentes com esses comportamentos incluem grãos, silos e clientes. Para resolver isso, Orleans introduzimos um padrão geral de ciclo de vida de componentes. Esse padrão consiste em um ciclo de vida observável, responsável por sinalizar estágios de inicialização e desligamento de um componente e observadores de ciclo de vida, responsáveis por executar operações de inicialização ou desligamento em estágios específicos.

Para obter mais informações, consulte Ciclo de vida de grãos e ciclo de vida de silos.

Ciclo de vida observável

Os componentes que precisam de inicialização e desligamento ordenados podem usar um ciclo de vida observável. Isso permite que outros componentes observem o ciclo de vida e recebam notificações quando um estágio específico é atingido durante a inicialização ou desligamento.

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

A chamada de inscrição registra um observador para receber notificações de quando um estágio é atingido durante a inicialização ou desligamento. O nome do observador é usado para fins de relatório. O estágio indica em que ponto na sequência de inicialização/desligamento o observador recebe a notificação. Cada estágio do ciclo de vida é observável. Todos os observadores são notificados quando o estágio é atingido durante a inicialização e o desligamento. Os estágios começam em ordem crescente e param em ordem decrescente. O observador pode cancelar a assinatura descartando o objeto descartável retornado.

Observador do ciclo de vida

Os componentes para participar do ciclo de vida de outro componente devem fornecer ganchos para seus comportamentos de inicialização e desligamento e inscrever-se em um estágio específico de um ciclo de vida observável.

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

Ambos ILifecycleObserver.OnStart e ILifecycleObserver.OnStop são chamados quando o estágio inscrito é atingido durante a inicialização ou desligamento.

Utilidades

Para conveniência, existem funções auxiliares para padrões comuns de uso do ciclo de vida.

Extensões

As funções de extensão estão disponíveis para assinar um ciclo de vida observável que não exige que o componente assinante implemente ILifecycleObserver. Em vez disso, eles permitem que os componentes passem lambdas ou funções membro para serem chamadas nos estágios subscritos.

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

Funções de extensão semelhantes permitem usar argumentos de tipo genérico em vez do nome do 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);

Participação no ciclo de vida

Alguns pontos de extensibilidade precisam de uma maneira de reconhecer quais componentes estão interessados em participar de um ciclo de vida. Uma interface de marcação de participante do ciclo de vida serve a essa finalidade. Mais detalhes sobre seu uso são abordados ao explorar ciclos de vida de silo e grãos.

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

Exemplo

Nos testes de ciclo de vida do Orleans, abaixo está um exemplo de um componente que participa de um ciclo de vida observável ao longo de múltiplas etapas.

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