如何将数据传递给`OnActivateAsync()`来初始化我的有状态演员?

Mau*_*les 5 c# azure-service-fabric service-fabric-actor

我正在创建一个可靠,有状态的服务演员.

题:

有没有办法在actor代理创建(ActorProxy.Create())期间传递初始化数据?基本上相当于我的演员的构造函数.

目前的想法:

我可以通过使用负责初始化状态的actor方法调用来跟进代理创建调用来实现这一点.

例如

//Danger, the following calls are not atomic
ITokenManager tokenActor = ActorProxy.Create<IMyActor>(actorId, "AppName");
//Something could happen here and leave my actor in an unknown state
await tokenActor.InitializeAsync(desiredInitialState);
Run Code Online (Sandbox Code Playgroud)

我对这种方法的关注:

  • 此操作不是原子操作.它可能会使我的演员处于不一致的状态
  • 这种初始化方法现在可以在演员的整个生命周期中使用,这是不希望的.

Jes*_*ter 2

这里有一些想法给你。其一,在 期间,演员本身真的无法获得初始化所需的数据吗OnActivateAsync?通常,如果我依赖于将一些初始数据输入到演员的状态中,我就会这样做。

protected override Task OnActivateAsync()
{
   if (State == null)
   {
       var initialState = await externalSource.GetSomeState();
       // simplified here but map the values properly onto the actual actor state
       this.State = initialState;
       return base.OnActivateAsync();
   }
}
Run Code Online (Sandbox Code Playgroud)

另一个想法是,如果您确实无法让参与者在其自己的激活期间检索数据,那么您很容易创建一个布尔属性,该属性是参与者状态的一部分,指示您正在谈论的其他激活是否具有曾经发生过。

 public Task InitializeAsync(State someState)
 {
     if (State.IsActivated)
     {
         // log out here that someone is attempting to reactivate when they shouldn't
         return Task.CompletedTask;
     }

     State = someState;
     State.IsActivated = true;
     return Task.CompletedTask;
 }
Run Code Online (Sandbox Code Playgroud)

这样,虽然从技术上讲,该方法可以在参与者的生命周期内被调用,但您有一个单线程保证,它只会在第一次被调用时真正执行某些操作。