Orleans overzicht van silolevenscyclus
Orleans silo's maken gebruik van een waarneembare levenscyclus voor geordende opstart- en afsluitsystemen Orleans , evenals toepassingslaagonderdelen. Zie de levenscyclus voor meer informatie over de implementatiedetails.Orleans
FASEN
Orleans silo- en clusterclients maken gebruik van een algemene set levenscyclusfasen van de service.
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: De eerste fase in de levenscyclus van de service.
- ServiceLifecycleStage.RuntimeInitialize: De initialisatie van de runtime-omgeving, waarbij de silo threading initialiseert.
- ServiceLifecycleStage.RuntimeServices: Het begin van runtimeservices, waarbij de silo netwerken en verschillende agents initialiseert.
- ServiceLifecycleStage.RuntimeStorageServices: De initialisatie van runtime-opslag.
- ServiceLifecycleStage.RuntimeGrainServices: Het begin van runtimeservices voor korrels. Dit omvat graantypebeheer, lidmaatschapsservice en grain-directory.
- ServiceLifecycleStage.ApplicationServices: De toepassingslaagservices.
- ServiceLifecycleStage.BecomeActive: De silo voegt het cluster toe.
- ServiceLifecycleStage.Active: De silo is actief in het cluster en kan de workload accepteren.
- ServiceLifecycleStage.Last: De laatste fase in de levenscyclus van de service.
Logboekregistratie
Vanwege de inversie van controle, waarbij deelnemers deelnemen aan de levenscyclus in plaats van de levenscyclus met een gecentraliseerde set initialisatiestappen, is het niet altijd duidelijk uit de code wat de opstart-/afsluitvolgorde is. Om dit te verhelpen, is logboekregistratie toegevoegd voordat silo wordt opgestart om te rapporteren welke onderdelen in elke fase deelnemen. Deze logboeken worden vastgelegd op het niveau van het informatielogboek op de Orleans.Runtime.SiloLifecycleSubject logboekregistratie. Bijvoorbeeld:
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"
Daarnaast worden timing- en foutgegevens op dezelfde manier vastgelegd voor elk onderdeel per fase. Bijvoorbeeld:
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."
Deelname aan de levenscyclus van silo's
Toepassingslogica kan deelnemen aan de levenscyclus van de silo door een deelnemende service te registreren in de servicecontainer van de silo. De service moet worden geregistreerd als een ILifecycleParticipant<TLifecycleObservable> locatie waar T
zich een ISiloLifecyclebevindt.
public interface ISiloLifecycle : ILifecycleObservable
{
}
public interface ILifecycleParticipant<TLifecycleObservable>
where TLifecycleObservable : ILifecycleObservable
{
void Participate(TLifecycleObservable lifecycle);
}
Wanneer de silo wordt gestart, mogen alle deelnemers (ILifecycleParticipant<ISiloLifecycle>
) in de container deelnemen door hun ILifecycleParticipant<TLifecycleObservable>.Participate gedrag aan te roepen. Zodra iedereen de mogelijkheid heeft gehad om deel te nemen, begint de waarneembare levenscyclus van de silo alle fasen op volgorde.
Opmerking
Met de introductie van de silolevenscyclus zijn bootstrapproviders, waarmee toepassingsontwikkelaars logica kunnen injecteren in de initialisatiefase van de provider, niet meer nodig, omdat toepassingslogica nu kan worden geïnjecteerd in elke fase van het opstarten van silo's. Niettemin hebben we een 'opstarttaak'-gevel toegevoegd om de overgang te helpen voor ontwikkelaars die bootstrap-providers hadden gebruikt. Als voorbeeld van hoe onderdelen kunnen worden ontwikkeld die deelnemen aan de levenscyclus van de silo, kijken we naar de opstarttaakfaçade.
De opstarttaak hoeft alleen de toepassingslogica over te nemen ILifecycleParticipant<ISiloLifecycle>
en te abonneren op de levenscyclus van de silo in de opgegeven fase.
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));
}
}
Uit de bovenstaande implementatie zien we dat in de Participate(...)
aanroep die wordt geabonneerd op de levenscyclus van de silo in de geconfigureerde fase, waarbij de callback van de toepassing wordt doorgegeven in plaats van de initialisatielogica. Onderdelen die in een bepaalde fase moeten worden geïnitialiseerd, bieden hun callback, maar het patroon is hetzelfde. Nu we ervoor StartupTask
zorgen dat de hook van de toepassing in de geconfigureerde fase wordt aangeroepen, moeten we ervoor zorgen dat de StartupTask
deelname aan de silolevenscyclus wordt uitgevoerd.
Hiervoor hoeven we deze alleen in de container te registreren. Dit doen we met een extensiefunctie op het ISiloHostBuildervolgende:
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;
}
Door de StartupTask te registreren in de servicecontainer van de silo als de markeringsinterface ILifecycleParticipant<ISiloLifecycle>
, geeft dit aan de silo aan dat dit onderdeel moet deelnemen aan de levenscyclus van de silo.