orleans icon indicating copy to clipboard operation
orleans copied to clipboard

Orleans.GRPC

Open shersh opened this issue 6 years ago • 20 comments

As described in issue https://github.com/dotnet/orleans/issues/3190 microservices become popular and of most popular solution is using protobuf with GRPC srevices. And I think it will be more interesting if use will have choice of using HTTP or GRPC to using Orleans backend.

So, what I propose is generating protobuf models from c# interfaces that could be translated to http\grpc with swagger support.

shersh avatar Aug 24 '19 13:08 shersh

This should be much easier to do in 3.0.0 with us using the Bedrock layer of ASP.NET Core.

sergeybykov avatar Aug 29 '19 17:08 sergeybykov

Could you explain how bedrock project can help with this?

shersh avatar Aug 30 '19 11:08 shersh

@ReubenBond has been working on that. He can explain better.

sergeybykov avatar Aug 30 '19 15:08 sergeybykov

@shersh An interesting read if you're unfamiliar with Bedrock:

https://github.com/aspnet/AspNetCore/issues/4772

mv10-work avatar Sep 10 '19 13:09 mv10-work

@mv10-work thanks, I reviewed it already, but I don't understand how it will help us with this issue. @ReubenBond could you explain?

shersh avatar Sep 10 '19 14:09 shersh

There are a couple of ways to think about gRPC support.

One is to use gRPC as a transport and that's what Bedrock support could help with since it allows substituting the transport.

The other, which I believe is more interesting & is what you're after, is to use gRPC as an interface to grains themselves. Marc Gravell has a 'code first' approach to gRPC using protobuf-net which I believe fits this purpose well. Adapting gRPC to support calling grains is a tractable problem.

gRPC isn't itself designed for object-style communication, however, so some kind of wrapper/support would be needed.

In my opinion it's a desirable feature as long as the user experience is good.

ReubenBond avatar Sep 11 '19 17:09 ReubenBond

Thanks, @ReubenBond. Coukd you explain, Bedrock project can help with http api support?

shersh avatar Sep 11 '19 17:09 shersh

@shersh Bedrock helps with the first option: using gRPC as a transport, which I wouldn't recommend pursuing. It does not help with the second option in which grains are exposed via gRPC

ReubenBond avatar Sep 11 '19 17:09 ReubenBond

@ReubenBond Thx, I see. But with exposing via http api (not GRPC) Bedrock can help?

shersh avatar Sep 13 '19 18:09 shersh

Bedrock isn't particularly helpful there, but there is a different feature which we added in 2.1 which helps: "Hosted Client". That feature is enabled by default and allows grain calls from any thread. That means that you can write an ASP.NET frontend to Orleans without needing to marshal calls onto the Orleans scheduler. So an HTTP/gRPC frontend can be hosted in the silo process quite easily.

ReubenBond avatar Sep 13 '19 21:09 ReubenBond

Nice news, @ReubenBond. Is there any docs or examples where I can read about it?

shersh avatar Sep 14 '19 06:09 shersh

@ReubenBond Using

Bedrock isn't particularly helpful there, but there is a different feature which we added in 2.1 which helps: "Hosted Client". That feature is enabled by default and allows grain calls from any thread. That means that you can write an ASP.NET frontend to Orleans without needing to marshal calls onto the Orleans scheduler. So an HTTP/gRPC frontend can be hosted in the silo process quite easily.

I would like to ask whether this is the preferred / recommended variant (API / BFF w/ Silo host) within the production deployment? Or is there still a separate concept where Silo is standalone and API / BFF is standalone solution connected via IClusterClient?

jurby avatar Sep 24 '19 19:09 jurby

How they gonna fit together? I mean Orleans is a tools for Actor Programing model but GRPC is a Remote Procedure Call System What does Orleans.GRPC exactly mean?

zeinali0 avatar Mar 07 '21 08:03 zeinali0

I'm currently writing a proto file to use to generate grpc services in the Generic Host that my silo runs in.

I am writing services to call grains via grpc.

It sucks to say the least.

I think Orleans.Grpc is meant to be the same as https://github.com/OrleansContrib/Orleans.Http

ElanHasson avatar Jul 09 '21 01:07 ElanHasson

gRPC as an interface to grains would be really interesting to allow developers to use any-front end technology they want with Orleans. For example, combining the Elixir Phoenix Framework on the front-end with .NET in the backend and Orleans as a middleware would constitute an interesting highly scalable web development stack.

However right now, this approach is not practical because there is too much boilerplate to write. Should Orleans add this feature, I think the focus should be put on code generation to empower users to have proto file generated from Grain Interfaces without needing to add data annotations or explicitly create separate contract classes.

nkosi23 avatar Mar 25 '22 11:03 nkosi23

@nkosi23 if we do add something like this (contributions more than welcome), I hope that we keep any additional code generation to an absolute minimum (ideally none): perhaps only including an indication of which gRPC interfaces are grain interfaces. I think it should heavily lean on the existing gRPC code generator / packages.

If we had support for calling into grains using gRPC, what do you imagine the code + developer experience should look like?

Again, contributions (first in the form of a proposal, then ideally a PR) are welcome.

ReubenBond avatar Mar 25 '22 14:03 ReubenBond

I think using gRPC as the interface transport to grains would make Orleans more service mesh friendly because service meshes (e.g., Linkerd) are able to understand/interpret gRPC communication, meaning gRPC communication is not "opaque" to service meshes, whereas Orleans' custom TCP transport is not understandable to service meshes and is therefore opaque to them, which means various service mesh features cannot be employed over Orleans silo-to-silo communication.

Furthermore, if Orleans were to be updated to use gRPC, then Orleans would benefit from functionality already provided by gRPC as well as new features/investments in the .NET gRPC library (e.g. HTTP/3 support).

I imagine gRPC's native support for client streaming and server streaming would also be useful for writing and reading Orleans streams. It would also make it easier to support direct streaming between grains (#7830).

bill-poole avatar Jul 21 '22 09:07 bill-poole

IMHO I think this would be better as a separate nuget package outside of orleans core codebase that would code gen grpc proxies to use against a grain client.

For dev ex:

  1. Add the NuGet with the source generator
  2. Configure some flags via attributes on grain interfaces level/method/assembly level attribute for your grain interfaces. Also support being able to have an assembly level attribute like [assembly:Orleans.Grpc.GenerateProxiesForSystemGrain] to expose system grains
  3. existing tools would generate the proto and models / grpc service interfaces and the source generator would create the C# grpc services, injecting IClusterClient.
  4. source generator would also generate an extension methods to add the generated grpc services to the ServiceCollection and another for the asp.net routing

Thoughts?

ElanHasson avatar Jul 25 '22 13:07 ElanHasson

@ElanHasson, I think there are two separate use cases for gRPC being discussed here:

  1. Use gRPC to communicate with Orleans grains from clients outside the Orleans cluster.
  2. Use gRPC for grain-to-grain communication.

Note that gRPC does not require that Protobuf be the serialization format - i.e., other formats may be used.

Am I correct in thinking that you are requesting functionality for use case 1? If so, why not host a gRPC endpoint on each silo and then invoke grains from there (translating from gRPC to native Orleans)? Are you proposing using Protobuf serialization, or native Orleans serialization over gRPC?

Also, if you have more than one silo, then there isn't any way for a client outside the cluster to work out which silo contains each grain - i.e., to which silo to route requests to each grain. Exposing a gRPC endpoint on every silo on the cluster means that requests from outside the cluster can be load balanced into the cluster and routed to the relevant grains from there.

Apologies if I've misunderstood.

I think there is real benefit for Orleans to use gRPC as its native grain-to-grain communication protocol, using whichever serializer is configured for the reasons I discussed here.

I would agree that a separate NuGet package outside of Orleans makes sense for use case 1, but not use case 2.

bill-poole avatar Jul 26 '22 09:07 bill-poole

Am I correct in thinking that you are requesting functionality for use case 1?

@bill-poole , you're correct. I missed that gRPC now supports any serialization format!

f you have more than one silo, then there isn't any way for a client outside the cluster to work out which silo contains each grain - i.e., to which silo to route requests to each grain.

It is my understanding that If the grain isn't on the silo you're connected to, Orleans routes the request to the grain on the correct silo. @ReubenBond is this understanding accurate?

I would agree that a separate NuGet package outside of Orleans makes sense for use case 1, but not use case 2.

Agreed

ElanHasson avatar Jul 26 '22 11:07 ElanHasson