Agregační služby
Služba Grain Services je vzdáleně přístupná, dělené služby pro podporu funkcí zrna. Každá instance obilné služby je odpovědná za určitou sadu zrn a tato zrnka mohou získat odkaz na obilnou službu, která je v současné době odpovědná za obsluhu pomocí GrainServiceClient
.
Služba Grain Services existuje pro případy podpory, kdy by se měla odpovědnost za obsluhu zrn distribuovat kolem clusteru Orleans . Připomenutí se například Orleans implementují pomocí odstupňovaných služeb: každý silo zodpovídá za zpracování operací připomenutí pro podmnožinu zrn a upozorňování těchto zrn při jejich vyvolání připomenutí.
Služba Grain Services se konfiguruje na silech a inicializuje se při spuštění sila před dokončením inicializace sila. Neshromažďují se při nečinnosti a místo toho mají životnost, která prodlužují životnost samotného sila.
Vytvoření služby GrainService
A GrainService je speciální agregační interval, který nemá žádnou stabilní identitu a spouští se v každém silu od spuštění po vypnutí. Při implementaci IGrainService rozhraní je potřeba provést několik kroků.
Definujte komunikační rozhraní odstupňované služby. Rozhraní objektu
GrainService
je sestaveno pomocí stejných principů, které byste použili k vytvoření rozhraní zrnitého intervalu.public interface IDataService : IGrainService { Task MyMethod(); }
Vytvořte odstupňovanou
DataService
službu. Je dobré vědět, že můžete také vložit, IGrainFactory abyste mohli provádět odstupňované hovory ze svéhoGrainService
.[Reentrant] public class DataService : GrainService, IDataService { readonly IGrainFactory _grainFactory; public DataService( IServiceProvider services, GrainId id, Silo silo, ILoggerFactory loggerFactory, IGrainFactory grainFactory) : base(id, silo, loggerFactory) { _grainFactory = grainFactory; } public override Task Init(IServiceProvider serviceProvider) => base.Init(serviceProvider); public override Task Start() => base.Start(); public override Task Stop() => base.Stop(); public Task MyMethod() { // TODO: custom logic here. return Task.CompletedTask; } }
[Reentrant] public class DataService : GrainService, IDataService { readonly IGrainFactory _grainFactory; public DataService( IServiceProvider services, IGrainIdentity id, Silo silo, ILoggerFactory loggerFactory, IGrainFactory grainFactory) : base(id, silo, loggerFactory) { _grainFactory = grainFactory; } public override Task Init(IServiceProvider serviceProvider) => base.Init(serviceProvider); public override Task Start() => base.Start(); public override Task Stop() => base.Stop(); public Task MyMethod() { // TODO: custom logic here. return Task.CompletedTask; } }
Vytvořte rozhraní pro GrainServiceClient<TGrainService>
GrainServiceClient
použití jinými zrny pro připojení k objektuGrainService
.public interface IDataServiceClient : IGrainServiceClient<IDataService>, IDataService { }
Vytvořte klienta odstupňované služby. Klienti obvykle fungují jako proxy služby, na které cílí, takže obvykle přidáte metodu pro každou metodu v cílové službě. Tyto metody budou muset získat odkaz na odstupňovanou službu, na kterou cílí, aby do ní mohli volat. Základní
GrainServiceClient<T>
třída poskytuje několik přetíženíGetGrainService
metody, které mohou vracet odkaz na agregační hodnoty odpovídajícíGrainId
, numerické hash (uint
) neboSiloAddress
. Druhá dvě přetížení jsou určená pro pokročilé případy, kdy vývojář chce použít jiný mechanismus pro mapování odpovědnosti na hostitele nebo chce adresovat hostitele přímo. V níže uvedeném vzorovém kódu definujeme vlastnost,GrainService
která vrátíIDataService
hodnotu pro agregační interval, který voláDataServiceClient
. K tomu použijemeGetGrainService(GrainId)
přetížení ve spojení sCurrentGrainReference
vlastností.public class DataServiceClient : GrainServiceClient<IDataService>, IDataServiceClient { public DataServiceClient(IServiceProvider serviceProvider) : base(serviceProvider) { } // For convenience when implementing methods, you can define a property which gets the IDataService // corresponding to the grain which is calling the DataServiceClient. private IDataService GrainService => GetGrainService(CurrentGrainReference.GrainId); public Task MyMethod() => GrainService.MyMethod(); }
Vytvořte skutečného klienta služby odstupňovaného provozu. Funguje jako proxy pro datovou službu. Bohužel musíte ručně zadat všechna mapování metod, což jsou jen jednoduché jednořádkové řádky.
public class DataServiceClient : GrainServiceClient<IDataService>, IDataServiceClient { public DataServiceClient(IServiceProvider serviceProvider) : base(serviceProvider) { } public Task MyMethod() => GrainService.MyMethod(); }
Vložte klienta služby zrnitosti do ostatních zrn, která ho potřebují. Není
GrainServiceClient
zaručeno přístup k místnímu siluGrainService
. Váš příkaz může být potenciálně odeslán do libovolnéhoGrainService
sil v clusteru.public class MyNormalGrain: Grain<NormalGrainState>, INormalGrain { readonly IDataServiceClient _dataServiceClient; public MyNormalGrain( IGrainActivationContext grainActivationContext, IDataServiceClient dataServiceClient) => _dataServiceClient = dataServiceClient; }
Nakonfigurujte klienta služby agregační a odstupňované služby v silu. Musíte to udělat, aby silo spustilo
GrainService
.(ISiloHostBuilder builder) => builder.ConfigureServices( services => services.AddGrainService<DataService>() .AddSingleton<IDataServiceClient, DataServiceClient>());
Další poznámky
Existuje metoda GrainServicesSiloBuilderExtensions.AddGrainService rozšíření, která se používá k registraci odstupňovaných služeb.
services.AddSingleton<IGrainService>(
serviceProvider => GrainServiceFactory(grainServiceType, serviceProvider));
Silo načte IGrainService
typy od poskytovatele služeb při spuštění: orleans/src/Orleans.Runtime/Silo/Silo.cs
var grainServices = this.Services.GetServices<IGrainService>();
MicrosoftGrainService
by měl projekt odkazovat.
Microsoft .Orleans. Na balíček NuGet OrleansRuntime by měl projekt odkazovat GrainService
.
Aby to fungovalo, musíte zaregistrovat službu i jeho klienta. Kód vypadá přibližně takto:
var builder = new HostBuilder()
.UseOrleans(c =>
{
c.AddGrainService<DataService>() // Register GrainService
.ConfigureServices(services =>
{
// Register Client of GrainService
services.AddSingleton<IDataServiceClient, DataServiceClient>();
});
})