orleans

Efficiently get state from Orleans Grain


I have a grain in Orleans for the players of a game. A player has several properties that I want to access directly in the client. Is it possible, is it efficient and does it make sense to have these as public properties on the grain? Or, should I have a GetAllState method that returns a DTO with the current value of these properties in the grain?

public interface IPlayerGrain : IGrainWithIntegerKey
{
    // Individual public properties to access grain state?
    string Name { get; }
    int Score { get; }
    int Health { get; }
 
    // Or, get all the current grain state as DTO?
    Task<PlayerState> GetAllState(); 
}

From my current understanding I think I will need to use GetAllState as I think any communication into the grain needs to be via a method and this may pass between silos. So, you probably want to minimise the number of messages passed and wouldnt want to pass three messages to get Name, Score and Health. Or, is message passing pretty cheap and not something I should worry about doing too much? In my example I've only included 3 properties, but in my real game there will be many more.

However, I don't really like the idea of having an anemic DTO model that is just a copy of the grain's internal properties.

So I was wondering if there was a better way, or a preferred pattern for this sort of thing in Orleans?


Solution

  • I think this depends a lot on the life cycle and access patterns of the properties. Do the properties tend to change independently or together? (At first glance, they seem to change independently and at quite different rates; I assume that Score and Health can change very frequently, but Name would almost never change.) And given that Name changes very infrequently, would it be a good fit for your access patterns to retrieve it every time you wanted an updated Score or Health value? Maybe Score and Health would be frequently accessed together, and Name along with other more static properties also belong together.

    If you let these kinds of questions drive your API before you think about the cost of message passing, you will probably find some good sweet spots (probably not the whole state of the grain). You might also consider having a Player grain and a PlayerStats grain that have different life cycles and that correspond more closely to the change rate of various pieces of data.