Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Orleans os silos usam um ciclo de vida observável para a inicialização e desligamento ordenados de sistemas e componentes da Orleans camada de aplicação. Para obter mais informações sobre os detalhes da implementação, consulte Orleans o ciclo de vida.
Estágios
Orleans os clientes de silo e cluster usam um conjunto comum de estágios de ciclo de vida do serviço:
public static class ServiceLifecycleStage
{
public const int First = int.MinValue;
public const int RuntimeInitialize = 2_000;
public const int RuntimeServices = 4_000;
public const int RuntimeStorageServices = 6_000;
public const int RuntimeGrainServices = 8_000;
public const int ApplicationServices = 10_000;
public const int BecomeActive = Active - 1;
public const int Active = 20_000;
public const int Last = int.MaxValue;
}
- ServiceLifecycleStage.First: o primeiro estágio no ciclo de vida do serviço.
- ServiceLifecycleStage.RuntimeInitialize: inicialização do ambiente de runtime, em que o silo inicializa o threading.
- ServiceLifecycleStage.RuntimeServices: início dos serviços de runtime, em que o silo inicializa a rede e vários agentes.
- ServiceLifecycleStage.RuntimeStorageServices: inicialização do armazenamento de runtime.
- ServiceLifecycleStage.RuntimeGrainServices: Início dos serviços de Runtime para grãos. Isso inclui o gerenciamento de tipos de grãos, o serviço de associação e o diretório de grãos.
- ServiceLifecycleStage.ApplicationServices: serviços de camada de aplicativo.
- ServiceLifecycleStage.BecomeActive: O silo se junta ao cluster.
- ServiceLifecycleStage.Active: O silo está ativo no cluster e pronto para aceitar a carga de trabalho.
- ServiceLifecycleStage.Last: o último estágio no ciclo de vida do serviço.
Registro
Devido à inversão de controle, em que os participantes ingressam no ciclo de vida em vez de o ciclo de vida ter um conjunto centralizado de etapas de inicialização, nem sempre fica claro no código qual é a ordem de inicialização/desligamento. Para ajudar a resolver isso, Orleans adiciona o log antes da inicialização do silo para relatar quais componentes participam em cada estágio. Esses logs são registrados no nível de log Informação no Orleans.Runtime.SiloLifecycleSubject registrador. Por exemplo:
Information, Orleans.Runtime.SiloLifecycleSubject, "Stage 2000: Orleans.Statistics.PerfCounterEnvironmentStatistics, Orleans.Runtime.InsideRuntimeClient, Orleans.Runtime.Silo"
Information, Orleans.Runtime.SiloLifecycleSubject, "Stage 4000: Orleans.Runtime.Silo"
Information, Orleans.Runtime.SiloLifecycleSubject, "Stage 10000: Orleans.Runtime.Versions.GrainVersionStore, Orleans.Storage.AzureTableGrainStorage-Default, Orleans.Storage.AzureTableGrainStorage-PubSubStore"
Além disso, Orleans também registra informações de tempo e erro para cada componente por estágio. Por exemplo:
Information, Orleans.Runtime.SiloLifecycleSubject, "Lifecycle observer Orleans.Runtime.InsideRuntimeClient started in stage 2000 which took 33 Milliseconds."
Information, Orleans.Runtime.SiloLifecycleSubject, "Lifecycle observer Orleans.Statistics.PerfCounterEnvironmentStatistics started in stage 2000 which took 17 Milliseconds."
Participação no ciclo de vida do Silo
A lógica do aplicativo pode participar do ciclo de vida do silo registrando um serviço participante no contêiner de serviço do silo. Registre o serviço como um ILifecycleParticipant<TLifecycleObservable>, em que T
é ISiloLifecycle.
public interface ISiloLifecycle : ILifecycleObservable
{
}
public interface ILifecycleParticipant<TLifecycleObservable>
where TLifecycleObservable : ILifecycleObservable
{
void Participate(TLifecycleObservable lifecycle);
}
Quando o silo é iniciado, todos os participantes (ILifecycleParticipant<ISiloLifecycle>
) no contêiner podem participar, tendo seu comportamento ILifecycleParticipant<TLifecycleObservable>.Participate ativado. Depois que todos tiverem tido a oportunidade de participar, o ciclo de vida observável do silo iniciará todos os estágios em ordem.
Exemplo
Com a introdução do ciclo de vida do silo, os provedores de inicialização, que anteriormente permitiam injetar lógica na fase de inicialização do provedor, não são mais necessários. Agora você pode injetar a lógica do aplicativo em qualquer estágio da inicialização do silo. No entanto, adicionamos uma fachada de "tarefa de inicialização" para ajudar na transição dos desenvolvedores que utilizaram provedores de bootstrap. Como exemplo de como você pode desenvolver componentes que participam do ciclo de vida do silo, vamos examinar a fachada da tarefa de inicialização.
A tarefa de inicialização só precisa herdar de ILifecycleParticipant<ISiloLifecycle>
e associar a lógica do aplicativo ao ciclo de vida do silo no estágio especificado.
class StartupTask : ILifecycleParticipant<ISiloLifecycle>
{
private readonly IServiceProvider _serviceProvider;
private readonly Func<IServiceProvider, CancellationToken, Task> _startupTask;
private readonly int _stage;
public StartupTask(
IServiceProvider serviceProvider,
Func<IServiceProvider, CancellationToken, Task> startupTask,
int stage)
{
_serviceProvider = serviceProvider;
_startupTask = startupTask;
_stage = stage;
}
public void Participate(ISiloLifecycle lifecycle)
{
lifecycle.Subscribe<StartupTask>(
_stage,
cancellation => _startupTask(_serviceProvider, cancellation));
}
}
Na implementação anterior, você pode ver que, na chamada Participate(...)
, é feita a inscrição no ciclo de vida do silo no estágio estabelecido, passando o retorno de chamada do aplicativo ao invés da lógica de inicialização. Componentes que precisam de inicialização em um determinado estágio forneceriam seu retorno de chamada, mas o padrão permanece o mesmo. Agora que você tem um StartupTask
que garante que o gancho do aplicativo seja chamado no estágio configurado, você precisa garantir que o StartupTask
participe do ciclo de vida do silo.
Para isso, você só precisa registrá-lo no contêiner. Faça isso usando uma função de extensão em ISiloHostBuilder:
public static ISiloHostBuilder AddStartupTask(
this ISiloHostBuilder builder,
Func<IServiceProvider, CancellationToken, Task> startupTask,
int stage = ServiceLifecycleStage.Active)
{
builder.ConfigureServices(services =>
services.AddTransient<ILifecycleParticipant<ISiloLifecycle>>(
serviceProvider =>
new StartupTask(
serviceProvider, startupTask, stage)));
return builder;
}
Ao registrar o StartupTask
no contêiner de serviço do silo como a interface de marcador ILifecycleParticipant<ISiloLifecycle>
, você sinaliza para o silo que esse componente precisa participar do ciclo de vida do silo.