Closed dsarfati closed 8 years ago
@dsarfati To add to the pool of options, one could create a constant, like ClusterSingletonGrainId
and use that.
Expanding on the idea, maybe even have a utility functions (functions with a name having domain meaning) that would return either a constant or a silo-specific ID or from a pool of IDs. Expanding that to further one might want to have a factory returning grains that'd also apply placement strategies to the grain in addition to the ID, going that path to DI...
@veikkoeeva Are you thinking that someone would want to specify the const id in a config file? A config file that allows switching between cluster vs silo singleton is interesting. What is the use case for a silo singleton?
@dsarfati I phrased poorly. I was thinking about raising visibility for this ID so that one wouldn't use a plain 0
, but some specific, named constant. Perhaps it'd be easier to catch a mistake in a review then.
A silo singleton, maybe one could be used to cache values locally to some silos in order to avoid hops to other silos and also spread some of the load from one grain to several. Some design patterns are discussed here. Also here are a few related ideas at https://github.com/dotnet/orleans/issues/447 and at https://github.com/dotnet/orleans/issues/446.
Sorry I was sluggish with getting back in touch with this.
@veikkoeeva no worries. I'll take a look at the links to get a better understanding. I was able to put in the code last night by simply using Guid.empty as the id. For the IGrainWithSingletonKey
@veikkoeeva As far as the Id goes, I was thinking the same thing. I was going to look into how the string keys worked and see if i could use the type name as the unique key so that each singleton would have its own key.
I have been thinking about ways to switch a singleton between cluster and silo. This seems like such a significant change in behavior that it may need to be to be a separate interface like a IGrainClusterSingleton
and IGrainSiloSingleton
. I could also do this with the config file and a single interface IGrainWithSingletonKey
but I was worried how much that would impact the system's behavior via a config file. If I do end up going down the config path I was going to default to cluster singleton and opt in to silo singletons.
This seems like an application level concern/practice, not something that Orleans itself should have knowledge of (as long as it doesn't constraint the implementation, which it doesn't).
There's many ways to do it, and depending on scalability needs, someone may need to switch from a single singleton, to a few singletons (just-a-few-tons?) to allow sharding for example. Or you might have a storage provider that you might want to use with long or guid keys, or whatever variation. Having this in the core seems to add more complexity than what it would solve (which is define an application level constant and let developers do GetGrain(MySingletonConstant)
(or even create an extension method).
Do you agree?
@jdom Seems pretty reasonable to me. The more I have been thinking about all the possible use cases for a "singleton" it seems like this should be moved up to the application levels as opposed to the framework. Our need for a cluster wide singleton are going to require a different implementation than required for some of the other discussions I have been reading. Im going to create a simple example using extensions and post my results so others can use it if they have the same need.
Great @dsarfati, Since we are in agreement that this is by design, I'll close this issue, and we can always re-open it if needed. BTW, regarding app design patterns, consider contributing to this too: https://github.com/OrleansContrib/DesignPatterns
We have a few places in our system that we are using cluster-level singleton grains by using the convention GetGrain(0). I was thinking about creating a new grain interface IGrainSingleton that would ensure that the same id is always used and eliminate the possibility of someone accidentally calling GetGrain(1) and getting a different grain. Looking at the code, this seems like a simple addition, but I didn't know if this was considered a bad practice. If this seems like a good idea, ill start working on it right away.