Sdílet prostřednictvím


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ů.

  1. 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();
    }
    
  2. 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ého GrainService.

    [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;
        }
    }
    
  3. Vytvořte rozhraní pro GrainServiceClient<TGrainService>GrainServiceClient použití jinými zrny pro připojení k objektu GrainService.

    public interface IDataServiceClient : IGrainServiceClient<IDataService>, IDataService
    {
    }
    
  1. 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) nebo SiloAddress. 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, GrainServicekterá vrátí IDataService hodnotu pro agregační interval, který volá DataServiceClient. K tomu použijeme GetGrainService(GrainId) přetížení ve spojení s CurrentGrainReference 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();
    }
    
  1. 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();
    }
    
  1. Vložte klienta služby zrnitosti do ostatních zrn, která ho potřebují. Není GrainServiceClient zaručeno přístup k místnímu silu GrainService . Váš příkaz může být potenciálně odeslán do libovolného GrainService sil v clusteru.

    public class MyNormalGrain: Grain<NormalGrainState>, INormalGrain
    {
        readonly IDataServiceClient _dataServiceClient;
    
        public MyNormalGrain(
            IGrainActivationContext grainActivationContext,
            IDataServiceClient dataServiceClient) =>
                _dataServiceClient = dataServiceClient;
    }
    
  2. 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. Modul runtime, silo/ Silo.cs

var grainServices = this.Services.GetServices<IGrainService>();

Microsoft.Orleans. Na balíček NuGet modulu GrainService runtime by měl projekt odkazovat.

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