在erlang中,你可以在产生它时将初始状态传递给actor。这样您就不需要处理初始状态的初始状态的init消息或者之前到达消息的消息。在奥尔良,假设谷物总是存在,你不能使用构造函数。有没有办法将初始状态传递给grain,从而避免任何init方法通过在任何其他方法之前调用它来破坏一致性?
当我说"把演员带到它的初始状态"时,我的意思是,在奥尔良语境中,调用特定粒子激活的init方法两次。这就像覆盖国家。也许你需要这个重置状态的消息之王,但如果你不需要它,那就是一个陷阱,一个潜在的错误来源。
我正在寻找某种类型的构造函数,例如来自erlang的spawn(module, function, [initial state])
。我的第一次尝试是使用以下签名寻找GetGrain的任何重载:GrainFactory.GetGrain<IGrain>(id, initialState);
答案 0 :(得分:3)
正如@svick建议的那样,OnActivateAsync
是加载谷物初始状态的最佳方法。
public class ExampleGrain : Orleans.Grain, IExampleGrain
{
public override Task OnActivateAsync()
{
// set initial state for grain
return base.OnActivateAsync();
}
...
每次初始化谷物时(而不仅仅是第一次)都会调用此方法。您可以使用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
答案 1 :(得分:0)
奥尔良的谷物一直存在,因此,每次激活谷物时,您都将[有条件地]重新初始化谷物。这真的是您想要做的吗?
好吧,如果您确实需要将特定的Grain初始化为特定的状态,则可以使用其键(字符串键或键的字符串部分)传递一些json。请记住,密钥在大小上有一些限制。
答案 2 :(得分:0)
我刚开始接触奥尔良,虽然看起来非常有前途,但我也一直难以理解这个初始状态问题。
对于通过参数修改行为的POCO,可以设置相关属性/字段的访问修饰符,使其只能由构造函数设置。这样,可以确保实例在构造后即可立即使用,并且实例的行为以后无法更改。但是在奥尔良,似乎没有任何方法可以实现相同的保证。看来我必须调用GetGrain来获取对Grain的引用,然后在其上调用某种初始化方法,然后再使用它。但这意味着我必须非常小心,以确保初始化方法仅在首次使用之前被调用一次。似乎很脆弱。
有一个假设,至少在 中,给定类型+密钥的谷物始终“存在”,并且GetGrain用于简单地从密钥空间中“查找”谷物。但是,当我使用Guid.NewGuid作为键来调用GetGrain时,很明显,我不希望谷物曾经存在过。我正在创造谷物,而不仅仅是找到它。在我看来,那时我应该有机会安全地对其进行初始化。
这是不可能的事实,这使我怀疑我缺少有关应该如何在实践中使用奥尔良的东西。谷物的身份是否应该完全定义其行为?如果没有,人们通常如何处理参数化行为?