Compartir a través de


Información general del ciclo de vida de grano

Orleans los granos usan un ciclo de vida observable (consulte Orleans Ciclo de vida) para la activación y desactivación ordenadas. Esto permite que la lógica del sistema, los componentes del sistema y la lógica de aplicación se inicien y detengan de forma ordenada durante la activación y la recopilación de granos.

Etapas

Las fases de ciclo de vida de grano predefinidas son las siguientes:

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

Aunque Orleans usa el ciclo de vida de grano durante la activación de los granos, estos no siempre se desactivan en algunos casos de error (como accidentes de silo). Por lo tanto, las aplicaciones no deben depender de que el ciclo de vida del componente se ejecute siempre durante las desactivaciones del componente.

Participación en el ciclo de vida de los granos

La lógica de la aplicación puede participar en el ciclo de vida de un grain de dos maneras:

  • El grano puede participar en su propio ciclo de vida.
  • Los componentes pueden acceder al ciclo de vida a través del contexto de activación de granos (consulte IGrainContext.ObservableLifecycle).

Un grano siempre participa en su ciclo de vida, por lo que la lógica de la aplicación se puede introducir invalidando el método de participación.

Participación de ejemplo

public override void Participate(IGrainLifecycle lifecycle)
{
    base.Participate(lifecycle);
    lifecycle.Subscribe(
        this.GetType().FullName,
        GrainLifecycleStage.SetupState,
        OnSetupState);
}

En el ejemplo anterior, Grain<TGrainState> sobrescribe el método Grain.Participate para indicar al ciclo de vida que llame a su método OnSetupState durante la etapa GrainLifecycleStage.SetupState del ciclo de vida.

Los componentes creados durante la construcción de un grano también pueden participar en el ciclo de vida sin agregar ninguna lógica de grano especial. Dado que Orleans crea el contexto del "grain" (IGrainContext), incluyendo su ciclo de vida (IGrainContext.ObservableLifecycle), antes de que se cree el "grain", cualquier componente insertado en el "grain" por el contenedor puede participar en el ciclo de vida del "grain".

Los componentes creados durante la construcción de un grano también pueden participar en el ciclo de vida sin agregar ninguna lógica de grano especial. Dado que Orleans crea el contexto de activación del grano (IGrainActivationContext), incluyendo su ciclo de vida (IGrainActivationContext.ObservableLifecycle), antes de la creación del grano, cualquier componente insertado en el grano por el contenedor puede participar en el ciclo de vida del grano.

Ejemplo: Participación de componentes

El componente siguiente participa en el ciclo de vida del grano cuando se crea utilizando su función de fábrica Create(...). Esta lógica podría existir en el constructor del componente, pero corre el riesgo de agregar el componente al ciclo de vida antes de que esté totalmente construido, lo que podría no 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
    }
}

Al registrar el componente de ejemplo en el contenedor de servicios mediante su función de fábrica Create(...), cualquier grano construido con el componente como dependencia hará que el componente participe en su ciclo de vida sin requerir ninguna lógica especial en el propio grano.

Registro de componentes en el contenedor

services.AddTransient<MyComponent>(sp =>
    MyComponent.Create(sp.GetRequiredService<IGrainContext>());
services.AddTransient<MyComponent>(sp =>
    MyComponent.Create(sp.GetRequiredService<IGrainActivationContext>());

Grano con componente como dependencia

public class MyGrain : Grain, IMyGrain
{
    private readonly MyComponent _component;

    public MyGrain(MyComponent component)
    {
        _component = component;
    }
}