0

AKKA アクターのセットを特定のコンテキストにバインドすることは可能ですか?

たとえば、私には 3 つのアクターがあり、それぞれがステート マシンを実装しています。これらのアクターは、特定の状態遷移で互いにメッセージを送信します。ここで、これらの状態をコンテキスト (ユーザー コンテキストなど) にバインドしたいと考えています。したがって、特定の状態にバインドされた一連のアクターを持つユーザー (userId で表される) がいます。このユーザー コンテキストが存在する限り、これらのアクター (または少なくともその状態) はユーザーのコンテキストにバインドする必要があります。これはAKKA自体で可能ですか、それともユーザーごとに異なるアクターの状態を保持する必要がありますか? それとも、アクターはこれらのユース ケース用に設計されていませんか?

4

1 に答える 1

3

私はあなたが求めていることを 100% 理解しているとは言えませんが、とにかく答えを探します。アクター システム自体は階層型です。階層には親子関係が存在し、親は子の所有者 (およびスーパーバイザー) になります。UserContextアクターを 3 つの子アクター (FSM アクター) の親としてシステムをモデル化した場合、子はこのUserContextアクター インスタンスにバインドされると思います。次の簡略化されたモデル例について考えてみましょう。

class UserContext extends Actor{
  val stateA = context.actorOf(Props[StateA])
  val stateB = context.actorOf(Props[StateB])
  val stateC = context.actorOf(Props[StateC])

  def receive = {
    case _ =>
  }
}

class StateA extends Actor{
  def receive = {
    case _ =>
  }
}

class StateB extends Actor{
  def receive = {
    case _ =>
  }
}

class StateC extends Actor{
  def receive = {
    case _ =>
  }
}

このように設定すると、状態の子は、このユーザー コンテキスト インスタンスが作成されると起動され、ユーザー コンテキスト インスタンスが停止されると停止されます。これで必要なのは、ユーザーごとに 1 つのユーザー コンテキストのみがシステムに存在することを確認するための小さなコードだけです。次のことを保証するために、次のようなことを行うことができます。

object UserContext{            
  def apply(username:String)(implicit system:ActorSystem):ActorRef = {
    val ctx = system.actorFor("/user/" + username)
    if (ctx.isTerminated){
      try{
        system.actorOf(Props[UserContext], username)
      }
      catch{
        case InvalidActorNameException(msg) if msg.contains("unique") => apply(username)
      }
    }
    else 
      ctx
  }
}

このファクトリ オブジェクトは、指定されたユーザー名のユーザー コンテキスト アクターが現在実行されていないことを確認します。そうであれば、その参照を返すだけです。そうでない場合は、それを起動し、後で検索できるようにユーザーの名前にバインドします。

このようなことをしたら、ファクトリを使用しUserContextて提供されたユーザー名を検索し、それを介してすべてのメッセージをルーティングし、メッセージを正しい子状態アクターに委任します。これは明らかにかなり単純化されていますが、あなたが望むものに似たものかもしれないと思います.

于 2013-06-28T12:17:47.867 に答える