Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os serviços de grãos são acessíveis remotamente, serviços particionados para suportar a 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 atendê-los usando um GrainServiceClient
.
Os serviços de grãos existem para apoiar os casos em que a responsabilidade pela prestação de serviços aos grãos deve ser distribuída no Orleans cluster. Por exemplo, Orleans os Lembretes são implementados usando serviços de grãos: cada silo lida com operações de lembrete para um subconjunto de grãos e notifica esses grãos quando seus lembretes são acionados.
Você configura serviços de grãos em silos. Eles inicializam quando o silo inicia, antes que o silo conclua a inicialização. Eles não são coletados quando ociosos; em vez disso, a sua vida útil prolonga-se pela vida útil do próprio silo.
Criar um serviço de grãos
A GrainService é um grão especial: não possui uma identidade estável e está presente em todos os silos desde a inicialização até ao encerramento. A implementação de uma IGrainService interface envolve várias etapas.
Defina a interface de comunicação do serviço de grão. Construa a interface de um
GrainService
usando os mesmos princípios que utiliza para construir uma interface granular.public interface IDataService : IGrainService { Task MyMethod(); }
Crie o
DataService
serviço de grãos. É útil saber que também é possível injetar um IGrainFactory para fazer chamadas de grãos a partir do teuGrainService
.[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 de serviço de grãos. Os clientes normalmente atuam como proxies para os serviços de grain que eles visam, então 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 alvo para que possam chamá-lo. A classe base
GrainServiceClient<T>
fornece várias sobrecargas do métodoGetGrainService
que podem retornar uma referência de grain correspondente a umGrainId
, um hash numérico (uint
) ou umSiloAddress
. As duas últimas sobrecargas destinam-se a casos avançados em que se pretende usar um mecanismo diferente para mapear responsabilidades para os hosts ou endereçar um host diretamente. No código de exemplo abaixo, definimos uma propriedade,GrainService
, que devolve oIDataService
para o grain que faz a chamada deDataServiceClient
. Para isso, usamos aGetGrainService(GrainId)
sobrecarga em conjunto com oCurrentGrainReference
imóvel.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 grãos nos outros grãos que precisam. O
GrainServiceClient
não tem garantia de aceder aoGrainService
no silo local. Seu comando pode ser enviado para oGrainService
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 grão e o cliente de serviço de grão no silo. Você precisa fazer isso para que o silo inicie o
GrainService
.(ISiloHostBuilder builder) => builder.ConfigureServices( services => services.AddGrainService<DataService>() .AddSingleton<IDataServiceClient, DataServiceClient>());
Notas adicionais
Há um método de extensão, GrainServicesSiloBuilderExtensions.AddGrainServiceusado 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>();
A Microsoft.Orleans. O pacote NuGet de tempo de execução deve ser referenciado GrainService
pelo projeto.
A Microsoft.Orleans. O pacote NuGet OrleansRuntime deve ser referenciado GrainService
pelo projeto.
Para que isso funcione, você deve registrar tanto o serviço quanto seu cliente. O código tem a seguinte aparência:
var builder = new HostBuilder()
.UseOrleans(c =>
{
c.AddGrainService<DataService>() // Register GrainService
.ConfigureServices(services =>
{
// Register Client of GrainService
services.AddSingleton<IDataServiceClient, DataServiceClient>();
});
})