Visão geral do ciclo de vida dos grãos
Orleans Os grãos usam um ciclo de vida observável (Ver Orleans Ciclo de Vida) para ativação e desativação ordenadas. Isso permite que a lógica de grãos, os componentes do sistema e a lógica do aplicativo sejam iniciados e interrompidos de forma ordenada durante a ativação e a coleta de grãos.
FASES
Os estágios pré-definidos do ciclo de vida do grão são os seguintes.
public static class GrainLifecycleStage
{
public const int First = int.MinValue;
public const int SetupState = 1_000;
public const int Activate = 2_000;
public const int Last = int.MaxValue;
}
First
: Primeira etapa do ciclo de vida de um grão.SetupState
: Configure o estado de grão, antes da ativação. Para grãos stateful, este é o estágio onde IStorage<TState>.State é carregado a partir do armazenamento, quando IStorage.RecordExists étrue
.Activate
: Estágio onde Grain.OnActivateAsync e Grain.OnDeactivateAsync são chamados.Last
: Última etapa do ciclo de vida de um grão.
Embora o ciclo de vida do grão seja usado durante a ativação do grão, uma vez que os grãos nem sempre são desativados durante alguns casos de erro (como falhas de silo), as aplicações não devem depender do ciclo de vida do grão sempre sendo executado durante as desativações de grãos.
Participação no ciclo de vida dos grãos
A lógica do aplicativo pode participar do ciclo de vida de um grão de duas maneiras:
- O grão pode participar no seu ciclo de vida.
- Os componentes podem acessar o ciclo de vida por meio do contexto de ativação de grãos (consulte IGrainContext.ObservableLifecycle).
- O grão pode participar no seu ciclo de vida.
- Os componentes podem acessar o ciclo de vida por meio do contexto de ativação de grãos (consulte IGrainActivationContext.ObservableLifecycle).
Um grão sempre participa de seu ciclo de vida, de modo que a lógica de aplicação pode ser introduzida substituindo o método participante.
Exemplo de participação
public override void Participate(IGrainLifecycle lifecycle)
{
base.Participate(lifecycle);
lifecycle.Subscribe(
this.GetType().FullName,
GrainLifecycleStage.SetupState,
OnSetupState);
}
No exemplo acima, Grain<TGrainState> substitui o Grain.Participate método para dizer ao ciclo de vida para chamar seu OnSetupState
método durante o GrainLifecycleStage.SetupState estágio do ciclo de vida.
Os componentes criados durante a construção de um grão também podem participar do ciclo de vida, sem a adição de qualquer lógica especial de grão. Uma vez que o contexto do grão (IGrainContext), incluindo o ciclo de vida do grão (IGrainContext.ObservableLifecycle), é criado antes do grão ser criado, qualquer componente injetado no grão pelo recipiente pode participar do ciclo de vida do grão.
Os componentes criados durante a construção de um grão também podem participar do ciclo de vida, sem a adição de qualquer lógica especial de grão. Como o contexto de ativação do grão (IGrainActivationContext), incluindo o ciclo de vida do grão (IGrainActivationContext.ObservableLifecycle), é criado antes de o grão ser criado, qualquer componente injetado no grão pelo recipiente pode participar do ciclo de vida do grão.
Exemplo de participação, criação e ativação
O componente a seguir participa do ciclo de vida do grão quando criado usando sua função Create(...)
de fábrica. Essa lógica pode existir no construtor do componente, mas isso corre o risco de o componente ser adicionado ao ciclo de vida antes de ser totalmente construído, o que pode não ser seguro.
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
public class MyComponent : ILifecycleParticipant<IGrainLifecycle>
{
public static MyComponent Create(IGrainActivationContext context)
{
var component = new MyComponent();
component.Participate(context.ObservableLifecycle);
return component;
}
public void Participate(IGrainLifecycle lifecycle)
{
lifecycle.Subscribe<MyComponent>(GrainLifecycleStage.Activate, OnActivate);
}
private Task OnActivate(CancellationToken ct)
{
// Do stuff
}
}
Ao registrar o componente de exemplo no contêiner de serviço usando sua Create(...)
função de fábrica, qualquer grão construído com o componente como uma dependência terá o componente participando de seu ciclo de vida sem qualquer lógica especial no grão.
Registrar componente no contêiner
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());
Grão com componente como dependência
public class MyGrain : Grain, IMyGrain
{
private readonly MyComponent _component;
public MyGrain(MyComponent component)
{
_component = component;
}
}