【问题标题】:How can I ensure orleans grain consistency?我怎样才能确保奥尔良谷物的一致性?
【发布时间】:2016-02-28 11:28:52
【问题描述】:

在 erlang 中,您可以在生成 actor 时将初始状态传递给它。这样你就不需要处理让actor再次进入初始状态的初始化消息,或者需要初始化消息的消息之前到达。在奥尔良,假设谷物始终存在,您不能使用构造函数。有什么方法可以将初始状态传递给grains,从而避免任何破坏一致性的init方法,因为它需要在任何其他方法之前被调用?

当我说“将actor带到它的初始状态”时,我的意思是,在奥尔良上下文中,调用特定grain激活的init方法两次。这就像覆盖状态。可能你需要这个重置状态的消息之王,但如果你不需要它,那就是一个陷阱,一个潜在的错误来源。

我正在寻找某种类型的构造函数,例如来自 erlang 的 spawn(module, function, [initial state])。我的第一次尝试是使用以下签名查找 GetGrain 的任何重载:GrainFactory.GetGrain<IGrain>(id, initialState);

【问题讨论】:

  • 也许我误解了一些东西,但你写道:“又是初始状态”和“颗粒总是存在”。您应该为新的“第一条”消息使用新的grain ID,并且将创建一个具有空状态的新grain。 “始终存在”并不意味着给定类型只有 1 个grain,它意味着从未手动创建或删除具有给定 ID 的grain,但框架会在首次使用给定 ID 时创建它们。
  • OnActivateAsync() 是您要查找的内容吗?似乎每当激活grain实例时都会调用它,因此您可以在那里初始化其字段。但我找不到任何合适的文档。
  • 不,这不是我要找的。 OneActivateAsync() 不需要任何参数,它只是一个事件回调,以便在激活grain 时进行某些操作。我正在寻找某种类型的构造函数,比如来自 erlang 的 spawn(module, function, [initial state])。我的第一次尝试是使用以下签名查找 GetGrain 的任何重载:GrainFactory.GetGrain<IGrain>(id, initialState);
  • 问题仍然存在:为什么要“重置”现有grain 的状态?为什么不使用新谷物?调用者设置grain的状态是不可能的,状态是grain的内部实现细节。但是你可以在 OnActivate 中设置一个默认的初始状态,当第一次激活时状态为空。

标签: c# erlang actor orleans


【解决方案1】:

正如@svick 建议的那样,OnActivateAsync 是加载颗粒初始状态的最佳方法。

 public class ExampleGrain : Orleans.Grain, IExampleGrain
 {

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

 ...

每次初始化grain时都会调用这个方法(不仅仅是第一次)。您可以使用 Orleans 中内置的 Persistence 基础设施来记录之前是否已创建grain(可能在您的状态类上使用布尔属性),即

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();
    }

有关持久性的更多信息,请参阅本教程:

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

【讨论】:

    【解决方案2】:

    Orleans 中的 Grain 始终存在,因此您的方法将 [有条件地] 每次激活该 Grain 时重新初始化它。这真的是你想要做的吗?

    好吧,如果你真的需要将具体grain初始化为具体的状态,那么你可以使用它的key(字符串key或者key的字符串部分)传入一些json。请记住,密钥的大小有一些限制。

    【讨论】:

      猜你喜欢
      • 2021-06-10
      • 1970-01-01
      • 2019-04-04
      • 2019-01-05
      • 2021-10-21
      • 2020-12-15
      • 1970-01-01
      • 2013-11-09
      • 2013-06-30
      相关资源
      最近更新 更多