5

信頼できるステートフルなサービス アクターを作成しています。

質問:

アクター プロキシの作成中に初期化データを渡す方法はありますか ( ActorProxy.Create())? 基本的に、私のアクターのコンストラクターに相当します。

現在の考え:

これは、状態の初期化を担当するアクター メソッド呼び出しでプロキシ作成呼び出しをフォローアップすることで実現できます。

例えば

//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);

そのようなアプローチに対する私の懸念:

  • この操作はアトミックではありません。アクターが一貫性のない状態になる可能性があります
  • この初期化メソッドは、望ましくないアクターの存続期間を通じて利用できるようになりました。
4

3 に答える 3

2

ここでいくつかの考えがあります。1 つには、初期化を行う必要があるデータは、実行中にアクター自体が実際に利用できないの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();
   }
}

もう 1 つの考えは、アクターが自身のアクティベーション中にデータを取得できない場合、アクターの状態の一部であるブール型プロパティを作成するのは非常に簡単であり、話している他のアクティベーションが持っているかどうかを示すことです。発生したことがあります。

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

このようにして、技術的にはアクターの存続期間中はメソッドを呼び出すことができますが、最初に呼び出されたときにのみ実際に何かを実行するというシングル スレッドの保証があります。

于 2016-02-24T20:36:18.060 に答える
1

アトミックな初期化を行う最善の方法は、初期化データを外部ストアに保持し、OnActivateAsync() 中にそのストアからこのデータを消費することです。

于 2016-02-24T18:54:02.050 に答える
0

プロキシの作成は、コンストラクターと同等ではありません。Service Fabric では、クライアントは、アクターが既に作成されているかどうかを知ることは想定されておらず、ライフサイクルはランタイムによって管理されます。

そのため、アクター自体はデフォルトの状態に初期化する必要があります。初期化呼び出しの前に他の呼び出しを防ぎ、必要に応じて複数の初期化を防ぐのは、アクター実装の仕事です。アクターは常にシングル スレッドであるため、ブール フラグなどを使用して簡単に実現できます。

于 2016-02-23T07:16:58.387 に答える