Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ensure orleans grain consistency?

In erlang you can pass initial state to actor when spawning it. This way you don't need to deal with init messages which take actor to it's initial state again or messages needing init message arrived before. In orleans given the assumption of grains always exist you can not use constructors. Is there any way to pass initial state to grains, avoiding thus any init method which break consistency by needing it to be called before any other method?

When I say "take actor to it's initial state", I mean, in orleans context, call init method of specific grain activation twice. It is like overwriting state. May be you need this king of message which reset state but if you don't need it, it is a pitfall, a potential source of bugs.

I'm looking for some type of constructor, something like spawn(module, function, [initial state]) from erlang. My first attempt was look for any overload of GetGrain with the following signature: GrainFactory.GetGrain<IGrain>(id, initialState);

like image 450
Guillermo Rdguez Glez Avatar asked Nov 25 '15 15:11

Guillermo Rdguez Glez


1 Answers

As @svick suggests, OnActivateAsync is the best approach for loading an initial state for a grain.

 public class ExampleGrain : Orleans.Grain, IExampleGrain
 {

   public override Task OnActivateAsync()
   {
        // set initial state for grain
        return base.OnActivateAsync();
    }

 ...

This method will be called every time the grain is initialised (not just the very first time). You could use the Persistence infrastructure built into Orleans to record whether the grain had been created previously (perhaps using a boolean property on your state class) i.e.

public class ExampleGrainState : GrainState
{
    public bool Initialised { get; set; }
}

[StorageProvider(ProviderName = "Storage")]
public class QuadKeyGrain : Orleans.Grain<ExampleGrainState>, IExampleGrain
{
    public override async Task OnActivateAsync()
    {
        if (!this.State.Initialised)
        {
            // do initialisation 
            this.State.Initialised = true;
            await this.WriteStateAsync();
        }
        await base.OnActivateAsync();
    }

See this tutorial for more information on persistence:

http://dotnet.github.io/orleans/Tutorials/Declarative-Persistence.html

like image 60
Richard Astbury Avatar answered Sep 28 '22 06:09

Richard Astbury