简体   繁体   English

如何确保奥尔良谷物的一致性?

[英]How can I ensure orleans grain consistency?

In erlang you can pass initial state to actor when spawning it.在erlang中,您可以在生成它时将初始状态传递给actor。 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.这样你就不需要处理 init 消息,这些消息将 actor 再次带到它的初始状态,或者需要 init 消息的消息之前到达。 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?有什么方法可以将初始状态传递给谷物,从而避免任何需要在任何其他方法之前调用而破坏一致性的 init 方法?

When I say "take actor to it's initial state", I mean, in orleans context, call init method of specific grain activation twice.当我说“让actor进入它的初始状态”时,我的意思是,在奥尔良上下文中,两次调用特定grain激活的init方法。 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.我正在寻找某种类型的构造函数,例如来自 erlang 的spawn(module, function, [initial state]) My first attempt was look for any overload of GetGrain with the following signature: GrainFactory.GetGrain<IGrain>(id, initialState);我的第一次尝试是使用以下签名查找 GetGrain 的任何重载: GrainFactory.GetGrain<IGrain>(id, initialState);

As @svick suggests, OnActivateAsync is the best approach for loading an initial state for a grain.正如@svick 所建议的, OnActivateAsync是加载谷物初始状态的最佳方法。

 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) ie您可以使用 Orleans 内置的 Persistence 基础结构来记录之前是否创建了谷物(可能使用状态类上的布尔属性),即

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 http://dotnet.github.io/orleans/Tutorials/Declarative-Persistence.html

Grains in Orleans are always exist, so you with your approach are going to [conditionally] re-initialize the grain every time when it gets activated. Orleans 中的 Grains 始终存在,因此您的方法将在每次激活时 [有条件地] 重新初始化 Grain。 Is this really what you want to be done?这真的是你想要做的吗?

Well, if you really need to initialize the specific grain to the specific state, then you can use its key (string key or string part of the key) to pass in some json.好吧,如果你真的需要将特定的grain初始化到特定的状态,那么你可以使用它的key(字符串key或者key的字符串部分)传入一些json。 Just remember that the key has some limitations for its size.请记住,密钥对其大小有一些限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM