Orleans Översikt över silolivscykeln
Orleans silor använder en observerbar livscykel för ordnad start och avstängning av Orleans system, samt komponenter i programskiktet. Mer information om implementeringsinformation Orleans finns i livscykeln.
STADIER
Orleans silo- och klusterklienter använder en gemensam uppsättning tjänstlivscykelsteg.
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: Den första fasen i tjänstens livscykel.
- ServiceLifecycleStage.RuntimeInitialize: Initieringen av körningsmiljön, där silo initierar trådning.
- ServiceLifecycleStage.RuntimeServices: Start av runtime-tjänster, där silo initierar nätverk och olika agenter.
- ServiceLifecycleStage.RuntimeStorageServices: Initieringen av körningslagring.
- ServiceLifecycleStage.RuntimeGrainServices: Start av körningstjänster för korn. Detta omfattar korntypshantering, medlemskapstjänst och kornkatalog.
- ServiceLifecycleStage.ApplicationServices: Tjänsterna på programnivå.
- ServiceLifecycleStage.BecomeActive: Silon ansluter till klustret.
- ServiceLifecycleStage.Active: Silon är aktiv i klustret och redo att acceptera arbetsbelastningen.
- ServiceLifecycleStage.Last: Den sista fasen i tjänstens livscykel.
Loggning
På grund av inversion av kontrollen, där deltagarna ansluter till livscykeln i stället för livscykeln med någon central uppsättning initieringssteg, framgår det inte alltid av koden vad start-/avstängningsordningen är. För att åtgärda detta har loggning lagts till innan silostarten för att rapportera vilka komponenter som deltar i varje steg. Dessa loggar registreras på informationsloggnivån i Orleans.Runtime.SiloLifecycleSubject loggen. Till exempel:
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"
Dessutom loggas tids- och felinformation på samma sätt för varje komponent efter steg. Till exempel:
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."
Deltagande i Silo-livscykel
Programlogik kan delta i silons livscykel genom att registrera en deltagande tjänst i silons tjänstcontainer. Tjänsten måste vara registrerad som en ILifecycleParticipant<TLifecycleObservable> där T
är en ISiloLifecycle.
public interface ISiloLifecycle : ILifecycleObservable
{
}
public interface ILifecycleParticipant<TLifecycleObservable>
where TLifecycleObservable : ILifecycleObservable
{
void Participate(TLifecycleObservable lifecycle);
}
När silon startar tillåts alla deltagare (ILifecycleParticipant<ISiloLifecycle>
) i containern att delta genom att anropa deras ILifecycleParticipant<TLifecycleObservable>.Participate beteende. När alla har haft möjlighet att delta startar silons observerbara livscykel alla steg i ordning.
Exempel
Med introduktionen av silolivscykeln är bootstrap-providers, som används för att tillåta programutvecklare att mata in logik i providerinitieringsfasen, inte längre nödvändiga, eftersom programlogik nu kan matas in i något skede av silostarten. Ändå lade vi till en "startuppgift" fasad för att underlätta övergången för utvecklare som hade använt bootstrap-leverantörer. Som ett exempel på hur komponenter kan utvecklas som deltar i silons livscykel tittar vi på fasaden för startuppgiften.
Startaktiviteten behöver bara ärva från ILifecycleParticipant<ISiloLifecycle>
och prenumerera på programlogik till silolivscykeln i den angivna fasen.
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));
}
}
Från implementeringen ovan kan vi se att den i anropet Participate(...)
prenumererar på silolivscykeln i den konfigurerade fasen och skickar programmets återanrop i stället för dess initieringslogik. Komponenter som måste initieras i ett visst skede skulle ge deras återanrop, men mönstret är detsamma. Nu när vi har en StartupTask
som säkerställer att programmets krok anropas i det konfigurerade stadiet måste vi se till att de StartupTask
deltar i silolivscykeln.
För detta behöver vi bara registrera den i containern. Vi gör detta med en tilläggsfunktion på 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;
}
Genom att registrera StartupTask i silons tjänstcontainer som markörgränssnittet ILifecycleParticipant<ISiloLifecycle>
signalerar detta till silon att den här komponenten måste delta i silolivscykeln.