6

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

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

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

4

2 回答 2

5

正如@svick 所建议的那样,OnActivateAsync这是加载谷物初始状态的最佳方法。

 public class ExampleGrain : Orleans.Grain, IExampleGrain
 {

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

 ...

每次初始化grain时都会调用这个方法(不仅仅是第一次)。您可以使用 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();
    }

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

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

于 2015-11-26T11:24:43.747 回答
0

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

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

于 2018-09-13T02:07:18.883 回答