Orleans Visão geral do ciclo de vida
Alguns Orleans comportamentos são suficientemente complexos para que precisem de inicialização e desligamento ordenados. Alguns componentes com tais comportamentos incluem grãos, silos e clientes. Para resolver este problema, foi introduzido um padrão geral do ciclo de vida dos componentes. Esse padrão consiste em um ciclo de vida observável, que é responsável pela sinalização nos estágios de inicialização e desligamento de um componente, e observadores do ciclo de vida que são 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 do grão e ciclo de vida do silo.
Ciclo de vida observável
Os componentes que precisam de inicialização e desligamento ordenados podem usar um ciclo de vida observável que permite que outros componentes observem o ciclo de vida e recebam uma notificação quando um estágio é atingido durante a inicialização ou o desligamento.
public interface ILifecycleObservable
{
IDisposable Subscribe(
string observerName,
int stage,
ILifecycleObserver observer);
}
A chamada de assinatura registra um observador para notificação quando um estágio é atingido ao iniciar ou parar. O nome do observador é para fins de relatório. A etapa indicada em que ponto da sequência de inicialização/desligamento o observador será notificado. Cada etapa do ciclo de vida é observável. Todos os observadores serão notificados quando o estágio for atingido ao iniciar e parar. Os estágios são iniciados em ordem crescente e interrompidos em ordem decrescente. O observador pode cancelar a inscrição descartando o descartável devolvido.
Observador do ciclo de vida
Os componentes que precisam participar do ciclo de vida de outro componente precisam fornecer ganchos para seus comportamentos de inicialização e desligamento e se inscrever 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/desligamento.
Utilitários
Por conveniência, foram criadas funções auxiliares para padrões comuns de utilização do ciclo de vida.
Extensões
Existem funções de extensão para subscrever um ciclo de vida observável que não requer que o componente de subscrição implemente ILifecycleObserver. Em vez disso, eles permitem que os componentes passem lambdas ou que a função de membros seja chamada nos estágios inscritos.
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 que argumentos de tipo genéricos sejam usados no lugar 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. Para este efeito, foi introduzida uma interface de marcação do participante do ciclo de vida. Mais informações sobre como isso é usado serão abordadas ao explorar os ciclos de vida de silos e grãos.
public interface ILifecycleParticipant<TLifecycleObservable>
where TLifecycleObservable : ILifecycleObservable
{
void Participate(TLifecycleObservable lifecycle);
}
Exemplo
A partir de nossos testes de ciclo de vida, abaixo está um exemplo de um componente que participa de um ciclo de vida observável em vários estágios do 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));
}
}