5

私はいくつかのakkaアクターを使用してシステムを監視しており、それぞれが異なるコンポーネントを担当しています。

一部のアクター操作は、並行して実行しないでください。そこで、ロックを保持するアクター(LockActor)を作成しました。アクターがそのような操作を実行したい場合、彼はLockActorに承認を求める必要があり、承認を得るまで操作を実行できません。

コードを単純にしたい場合は、要求されたアクターで次のようなことを行う必要があります。

while (LockActor.isLockHold()) {
    // perform the operation
}

これはもちろん、アクターシステムの設計全体を壊します...

したがって、コードを少し複雑にするメッセージを使用する必要があります。

  1. アクターBはLockRequestMessageをLockActorに送信する必要があります
  2. LockActorは、ロック要求を保持するキューを保持しています
  3. ロックが可能な場合、LockActorはLockApprovalMessageをキューの最初のアクターに送信します
  4. アクターBがLockApprovalMessageを(必ずしもすぐにではなく)受信すると、LockRequestMessageを送信したときに必要だった特定の操作を実行する必要があります(各アクターは、ロックを必要とする複数の操作を持つことができます)

だから私の質問は-アクターシステムの設計を壊さずにそのようなことを実装するが、それでもコードを可能な限り単純に保つ最良の方法は何ですか?

4

3 に答える 3

6

ロックを取得するために 1 つのアクターを使用する代わりに、作業に 1 つのアクターを使用してみませんか? これは、アクター モデルで推奨される方法です。

于 2012-11-26T09:59:03.883 に答える
4

ここには2つの解決策があります。

まず、ask パターンを使用できます:

class MyActor extends Actor {

    def receive = {
        case Start: {
            val f = lockActor ? LockRequestMessage
            f onSuccess {
                case LockApprovalMessage => {
                    //todo: do your thing
                }
            }
        }
    }

}

ask メソッドは、リクエスト メッセージを受信して​​将来を完了する別のアクターを作成することに注意してください。詳細については、ドキュメントを参照してください。

ask パターンを使用したくない場合は、次のように、become-unbecome メカニズムをうまく使用できます。

class MyActor extends Actor {
    import context._

    def receive = {
        case Start: {
            lockActor ! LockRequestMessage
            become(waitForApproval)
        }
    }    

    def waitForApproval = {
        case LockApprovalMessage => {
            //todo: do your thing
        }
    }


}

同じ受信関数内で 2 つのメッセージを適切に処理できますが、ある時点でのアクターの状態を記録する必要があります。ならないメカニズムは、あなたのためにこのきれいな分離を行います。

アクターが一部の共有リソースを変更するのを防ぐためにロックを使用している場合、Akka はこれに対していくつかのより洗練されたメカニズムを提供することに注意してください。

ドキュメントを見てください - 実装が大幅に簡素化される可能性があります。

于 2012-11-26T12:54:21.000 に答える
0

これがアイデアです。私はscalaの初心者なので、詳細はわかりません。

  • カスタムクラスActorExecutorを作成します。これは、メッセージとしてクロージャを受け入れる型付きアクターであり、そのクロージャを呼び出すことによってそのメッセージを処理します。

  • ロックごとに、ActorExecutorのインスタンスを作成します

  • アクターがロックホールドを使用してアクションを実行する場合は常に、そのロックを表すクロージャーをActorExecutorに送信します。

このようにして、具象ActorExecutorインスタンスに送信されるすべてのアクションが順番に実行されます。

于 2012-11-26T11:53:21.680 に答える