Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os serviços de grãos são serviços particionados e acessíveis remotamente para dar suporte à funcionalidade de grãos. Cada instância de um serviço de grãos é responsável por algum conjunto de grãos. Esses grãos podem obter uma referência ao serviço de grãos atualmente responsável por servi-los usando um GrainServiceClient
.
Os serviços de grãos existem para dar suporte a casos em que a responsabilidade pela manutenção de grãos deve ser distribuída ao redor do Orleans cluster. Por exemplo, Orleans lembretes são implementados usando serviços de grãos: cada silo realiza operações de lembrete para um subconjunto de grãos e notifica esses grãos quando seus lembretes são acionados.
Você configura os serviços de armazenamento de grãos em silos. Eles inicializam quando o silo é iniciado, antes que o silo conclua a inicialização. Eles não são coletados quando ociosos; em vez disso, suas vidas se estendem pelo tempo de vida do silo em si.
Criar um serviço de grãos
A GrainService é um grão especial: ele não tem identidade estável e passa por cada silo do início ao final do processo. A implementação de uma IGrainService interface envolve várias etapas.
Defina a interface de comunicação do serviço de granularidade. Crie a interface de um
GrainService
usando os mesmos princípios que você usa para criar uma interface de grain.public interface IDataService : IGrainService { Task MyMethod(); }
Crie o serviço de granularidade
DataService
. É útil saber que você também pode injetar um IGrainFactory e poder fazer chamadas para os grains a partir do seuGrainService
.[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; } }
Crie uma interface para o GrainServiceClient<TGrainService>
GrainServiceClient
que outros grãos usarão para se conectar aoGrainService
.public interface IDataServiceClient : IGrainServiceClient<IDataService>, IDataService { }
Crie o cliente do serviço de granularidade. Normalmente, os clientes atuam como proxies para os serviços de granulação que eles destinam, portanto, você geralmente adiciona um método para cada método no serviço de destino. Esses métodos precisam obter uma referência ao serviço de grãos de destino para que possam chamá-lo. A classe base
GrainServiceClient<T>
fornece várias sobrecargas de métodoGetGrainService
que podem retornar uma referência de grão correspondente a umGrainId
, um hash numérico (uint
) ou umSiloAddress
. As duas últimas sobrecargas são para casos avançados em que você deseja usar um mecanismo diferente para mapear a responsabilidade para hosts ou abordar um host diretamente. No código de exemplo abaixo, definimos uma propriedade,GrainService
, que retorna oIDataService
para o grão que chama oDataServiceClient
. Para fazer isso, usamos a sobrecargaGetGrainService(GrainId)
em conjunto com a propriedadeCurrentGrainReference
.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(); }
Injete o cliente de serviço de granularidade nas outras granularidades que precisam dele.
GrainServiceClient
não é garantido acessarGrainService
no silo local. Seu comando pode potencialmente ser enviado aoGrainService
em qualquer silo no cluster.public class MyNormalGrain: Grain<NormalGrainState>, INormalGrain { readonly IDataServiceClient _dataServiceClient; public MyNormalGrain( IGrainActivationContext grainActivationContext, IDataServiceClient dataServiceClient) => _dataServiceClient = dataServiceClient; }
Configure o serviço de granularidade e o cliente do serviço de granularidade no silo. Você precisa fazer isso para que o silo inicie o
GrainService
.(ISiloHostBuilder builder) => builder.ConfigureServices( services => services.AddGrainService<DataService>() .AddSingleton<IDataServiceClient, DataServiceClient>());
Observações adicionais
Há um método de extensão, GrainServicesSiloBuilderExtensions.AddGrainService usado para registrar serviços de grãos.
services.AddSingleton<IGrainService>(
serviceProvider => GrainServiceFactory(grainServiceType, serviceProvider));
O silo busca IGrainService
tipos do provedor de serviços ao iniciar (consulte orleans/src/Orleans.Runtime/Silo/Silo.cs):
var grainServices = this.Services.GetServices<IGrainService>();
O pacote NuGet Microsoft.Orleans.Runtime deve ser referenciado pelo projeto GrainService
.
O pacote NuGet Microsoft.Orleans.OrleansRuntime deve ser referenciado pelo projeto GrainService
.
Para que isso funcione, você deve registrar o serviço e seu cliente. O código fica mais ou menos parecido com isto:
var builder = new HostBuilder()
.UseOrleans(c =>
{
c.AddGrainService<DataService>() // Register GrainService
.ConfigureServices(services =>
{
// Register Client of GrainService
services.AddSingleton<IDataServiceClient, DataServiceClient>();
});
})