Bagikan melalui


Layanan Biji-Bijian

Layanan Biji-Bijian dapat diakses dari jarak jauh, layanan yang dipartisi untuk mendukung butir fungsionalitas. Setiap instans layanan biji-bijian bertanggung jawab atas beberapa set biji-bijian dan biji-bijian tersebut bisa mendapatkan referensi ke layanan biji-bijian yang saat ini bertanggung jawab untuk melayani mereka dengan menggunakan GrainServiceClient.

Grain Services ada untuk mendukung kasus di mana tanggung jawab untuk melayani biji-bijian harus didistribusikan di Orleans sekitar kluster. Misalnya, Orleans Pengingat diimplementasikan menggunakan layanan biji-bijian: setiap silo bertanggung jawab untuk menangani operasi pengingat untuk subset biji-bijian dan memberi tahu biji-bijian tersebut saat pengingat mereka diaktifkan.

Layanan Biji-Bijian dikonfigurasi pada silo dan diinisialisasi ketika silo dimulai, sebelum silo menyelesaikan inisialisasi. Mereka tidak dikumpulkan ketika menganggur dan sebaliknya memiliki masa pakai yang memperpanjang masa pakai silo itu sendiri.

Membuat GrainService

GrainService adalah biji-bijian khusus; yang tidak memiliki identitas stabil, dan berjalan di setiap silo dari startup ke shutdown. Ada beberapa langkah yang terlibat saat mengimplementasikan antarmuka IGrainService.

  1. Tentukan antarmuka komunikasi layanan biji-bijian. Antarmuka dibangun GrainService menggunakan prinsip yang sama yang akan Anda gunakan untuk membangun antarmuka biji-bijian.

    public interface IDataService : IGrainService
    {
        Task MyMethod();
    }
    
  2. DataService Buat layanan biji-bijian. Ada baiknya untuk mengetahui bahwa Anda juga dapat menginjeksi IGrainFactory, sehingga Anda dapat melakukan panggilan butir dari GrainService Anda.

    [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. Buat antarmuka untuk GrainServiceClient<TGrainService>GrainServiceClient supaya digunakan oleh butir lain untuk terhubung ke GrainService.

    public interface IDataServiceClient : IGrainServiceClient<IDataService>, IDataService
    {
    }
    
  1. Buat klien layanan biji-bijian. Klien biasanya bertindak sebagai proksi untuk layanan biji-bijian yang mereka targetkan, sehingga Anda biasanya akan menambahkan metode untuk setiap metode pada layanan target. Metode ini perlu mendapatkan referensi ke layanan biji-bijian yang mereka targetkan sehingga mereka dapat memanggilnya. Kelas GrainServiceClient<T> dasar menyediakan beberapa kelebihan beban GetGrainService metode yang dapat mengembalikan referensi biji-bijian GrainIdyang sesuai dengan , hash numerik (uint), atau SiloAddress. Dua kelebihan beban terakhir adalah untuk kasus lanjutan di mana pengembang ingin menggunakan mekanisme yang berbeda untuk memetakan tanggung jawab kepada host atau ingin mengatasi host secara langsung. Dalam kode sampel kami di bawah ini, kami mendefinisikan properti, GrainService, yang mengembalikan IDataService untuk biji-bijian yang memanggil DataServiceClient. Untuk melakukan itu, kita menggunakan GetGrainService(GrainId) kelebihan beban bersama dengan CurrentGrainReference properti .

    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. Buat klien layanan butir yang sebenarnya. Ini hanya bertindak sebagai proksi untuk layanan data. Sayangnya, Anda harus mengetikkan semua pemetaan metode secara manual, yang hanya berupa satu-baris sederhana.

    public class DataServiceClient : GrainServiceClient<IDataService>, IDataServiceClient
    {
        public DataServiceClient(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }
    
        public Task MyMethod() => GrainService.MyMethod();
    }
    
  1. Injeksi klien layanan butir ke dalam butir lain yang membutuhkannya. GrainServiceClient tidak dijamin untuk mengakses GrainService pada silo lokal. Perintah Anda berpotensi dikirim ke GrainService pada silo apa pun di dalam kluster.

    public class MyNormalGrain: Grain<NormalGrainState>, INormalGrain
    {
        readonly IDataServiceClient _dataServiceClient;
    
        public MyNormalGrain(
            IGrainActivationContext grainActivationContext,
            IDataServiceClient dataServiceClient) =>
                _dataServiceClient = dataServiceClient;
    }
    
  2. Konfigurasikan layanan biji-bijian dan klien layanan biji-bijian di silo. Anda perlu melakukan ini, sehingga silo akan memulai GrainService.

    (ISiloHostBuilder builder) =>
        builder.ConfigureServices(
            services => services.AddGrainService<DataService>()
                                .AddSingleton<IDataServiceClient, DataServiceClient>());
    

Catatan tambahan

Ada metode GrainServicesSiloBuilderExtensions.AddGrainService ekstensi yang digunakan untuk mendaftarkan layanan biji-bijian.

services.AddSingleton<IGrainService>(
    serviceProvider => GrainServiceFactory(grainServiceType, serviceProvider));

Silo mengambil IGrainService jenis dari penyedia layanan saat memulai: orleans/src/Orleans. Runtime/Silo/Silo.cs

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

Microsoft .Orleans. Paket Runtime NuGet harus dirujuk oleh GrainService proyek.

Microsoft .Orleans.OrleansPaket Runtime NuGet harus dirujuk oleh GrainService proyek.

Agar ini berfungsi, Anda harus mendaftarkan layanan dan juga kliennya. Kode terlihat seperti ini:

var builder = new HostBuilder()
    .UseOrleans(c =>
    {
        c.AddGrainService<DataService>()  // Register GrainService
        .ConfigureServices(services =>
        {
            // Register Client of GrainService
            services.AddSingleton<IDataServiceClient, DataServiceClient>();
        });
    })