Orleans: Documentation for GrainServices

Created on 11 Jun 2018  路  15Comments  路  Source: dotnet/orleans

@JillHeaden, I made this during a gitter conversation, hopefully it'll be of some use to whoever's making Orleans documentation :)

https://docs.google.com/document/d/1JW8nJW8yK7ZhzO_pMWgWUfMNMq8og90qBmCWdOaX9iQ/edit#

documentation

Most helpful comment

@skyflyer No worries. It's a sign that our docs aren't clear enough.

I see now that by "service" you mean something injected vi DI. Grain services have nothing to do with DI. A grain service is rather a distributed (across the cluster) and scalable (with the number of silos) piece of application functionality where every instance of it is responsible for a partition of the whole address space.

An example is the Reminder Service. Every silo runs a partition (a grain service grain) of the Reminder Service. When a grain (any grain of any type of the application) needs to register a reminder, the registration request gets automatically routed to the partition (silo and reminder service grain) that is responsible for the range of grain IDs in which the calling grain's ID falls into. That partition hold data for all reminders for all grains in that range of grain IDs and is responsible for sending reminder messages when the time is due. Collectively, all instances (partitions) of the Reminder Service grain service cover the whole address space of all possible grain IDs.

All 15 comments

Thank you, @bboyle1234!

Yes, Thank you!! @bboyle1234

Could someone please elaborate on the differences between GrainServices and plain Services? It seems that GrainService implementation is a bit more convoluted (with regards to grain service client). What benefits does a GrainService have over, say, plain service?

If some grains need an API client for external communication (which uses HttpClient internally), I suppose I can provide a singleton registration (services.AddSingleton<SomeApiClient>()), which will be injected into the grains requiring this functionality.

Or is this not the case? In which cases would one prefer to use GrainService (with its proxy GrainServiceClient)?

Is the following statement from http://dotnet.github.io/orleans/Documentation/grains/grainservices.html confusing?

A GrainService is a special grain; one that has no identity, and runs in every silo from startup to shutdown.

Closing this issue because documentation for grain services has been added. Thank you @bboyle1234 for your contribution!

For related questions please open new issues if necessary.

@sergeybykov,

Is the following statement from http://dotnet.github.io/orleans/Documentation/grains/grainservices.html confusing?

Unfortunately it does not address the difference between "plain service" and "grain service". It addresses only the difference between a "normal grain" and "service grain". Come to think of it, I wonder what if the only difference between "grain service" and "stateless worker grain" is its activation? Perhaps it is just my limited understanding, since I'm new to Orleans.

I don't think opening a new issue about this will be productive, so I'm following up here.

@skyflyer What do you mean by "plain service"?

Grains are virtual in nature - they get activated and deactivated on different silos in the cluster over time. To get activated, a grain needs a request to be sent to it.

A way to think about a grain service is as of a collection of grain-like objects with a fixed distribution of one per silo that stay activated the whole time a silo is running. This collection is presented to callers as a single service with requests being getting automatically routed to one of the grain service instances (grains) based on the partition key.

Does this help?

@sergeybykov, I suppose it is my lack of understanding. I'm sorry if I'm being obtuse. Let me try to explain on an example.

The docs use IDataService in the example with a single method Task MyMethod(). If a "plain service" (implementation below) is registered with a singleton scope, what is the (functional) difference between this plain service and a LightstreamerDataService in the example? Is the activation of the service on startup the only difference or am I missing some piece of the puzzle?

Implementation:

c# public class LightstreamerDataService : IDataService { public Task MyMethod() { return Task.CompletedTask; } }

@skyflyer No worries. It's a sign that our docs aren't clear enough.

I see now that by "service" you mean something injected vi DI. Grain services have nothing to do with DI. A grain service is rather a distributed (across the cluster) and scalable (with the number of silos) piece of application functionality where every instance of it is responsible for a partition of the whole address space.

An example is the Reminder Service. Every silo runs a partition (a grain service grain) of the Reminder Service. When a grain (any grain of any type of the application) needs to register a reminder, the registration request gets automatically routed to the partition (silo and reminder service grain) that is responsible for the range of grain IDs in which the calling grain's ID falls into. That partition hold data for all reminders for all grains in that range of grain IDs and is responsible for sending reminder messages when the time is due. Collectively, all instances (partitions) of the Reminder Service grain service cover the whole address space of all possible grain IDs.

Grain services have nothing to do with DI

OK. I guess I was confused by the injection of IDataServiceClient in the example, which is, if I understand this correctly, used to access the LightstreamerDataService.

Yes, in the example DI is used only to inject a singleton client to grains in the silo, so that they can all share it as a proxy for talking to the LightstreamerDataService that spans the cluster as a partitioned distributed application service.

@skyflyer What do you mean by "plain service"?

Grains are virtual in nature - they get activated and deactivated on different silos in the cluster over time. To get activated, a grain needs a request to be sent to it.

A way to think about a grain service is as of a collection of grain-like objects with a fixed distribution of one per silo that stay activated the whole time a silo is running. This collection is presented to callers as a single service with requests being getting automatically routed to one of the grain service instances (grains) based on the partition key.

Does this help?

@skyflyer No worries. It's a sign that our docs aren't clear enough.

I see now that by "service" you mean something injected vi DI. Grain services have nothing to do with DI. A grain service is rather a distributed (across the cluster) and scalable (with the number of silos) piece of application functionality where every instance of it is responsible for a partition of the whole address space.

An example is the Reminder Service. Every silo runs a partition (a grain service grain) of the Reminder Service. When a grain (any grain of any type of the application) needs to register a reminder, the registration request gets automatically routed to the partition (silo and reminder service grain) that is responsible for the range of grain IDs in which the calling grain's ID falls into. That partition hold data for all reminders for all grains in that range of grain IDs and is responsible for sending reminder messages when the time is due. Collectively, all instances (partitions) of the Reminder Service grain service cover the whole address space of all possible grain IDs.

I think it's worth adding these comments to the FAQ or the grain service doc.
I will send a PR if you agree.

I agree - this should probably go to the grain services doc in some form. A PR will be much appreciated.

Pinging @sergeybykov and @patricksuo on this one, I just went down the same rabbit hole and this clarification would have been nice in the docs. (Unfortunately, from work I can't do anything in public-repos, and I have limited spare time right now).

(Did you folks lose the assistance of Jill H. for docs? I know docs are a ton of work, but they're so far out of date now it's getting painful -- meant as constructive feedback only! MS needs to throw you folks some resources...)

Yeah, we haven't had a tech writer for more than a year now. Any help would be greatly appreciated.

Was this page helpful?
0 / 5 - 0 ratings