3

非常にまれにしか変更されないグローバル変数(シングルトン)が1つ必要です。実際には、アクターが再起動し、変数を再初期化したときにのみ変更されます。コンパニオンオブジェクトのシングルトンvalではこれを行うことができないため、var(可変)として宣言する必要があります。

object UserDatabase {
    var dbConnection = "" // initializing db connection
}

私が読んだ多くのガイドラインは、常に可変状態の共有に反対しています。そこで、変数をクラスに移動し、メッセージパッシングを使用して変数を取得します。

class UserDatabase extends Actor{
    val dbConnection = "" // initializing db connection locally
    def receive = {case GetConnection => self.reply(dbConnection)}
}

問題は、dbConnectionは多くのアクターによって非常に頻繁にアクセスされ、メッセージを継続的に送信するとパフォーマンスが低下することです(akkaはメールボックスを1つずつ処理するため)。

パフォーマンスを犠牲にせずにこれを行う方法がわかりません。何か案が?

4

4 に答える 4

3

おそらく代わりにエージェントを使用しますか?http://akka.io/docs/akka/1.2-RC6/scala/agents.html

于 2011-09-05T19:34:40.483 に答える
2

まず、実際にパフォーマンスの低下を測定/通知しましたか? メッセージングは​​軽量であるため、アプリケーションにとって十分に高速である可能性があります。

次に、考えられる解決策: 「グローバル」状態がめったに書き込まれないが、非常に頻繁にアクセスされる場合は、プッシュ戦略を選択できます。変更されるたびに、UserDatabaseアクターは更新された値を関心のあるアクターに送信します。その後、パブリッシュ/サブスクライブ アプローチを使用したり、アクター レジスタに依存したり、アクターのプールを使用したりできます。

class UserDatabase extends Actor{
    var dbConnection = "" // initializing db connection locally
    def receive = {
      case SetConnection( newConnection ) if dbConnection != newConnection => {
        dbConnection = newConnection
        sendUpdatedConnection(); // sends the change to every relevant actor
      }
    }
}
于 2011-09-05T15:18:34.273 に答える
1

どのような場合でも、変数を頻繁に使用する必要がない場合は、それを にするか、変数へのすべてのアクセスをブロックで (変数で)java.lang.concurrent.atomic.AtomicReferenceラップする方が簡単で効率的です。synchronizedアクターは常に物事をより簡単かつ安全にするわけではありません。

于 2011-09-05T16:42:08.377 に答える
0
  1. RoundRobinRouter のルートとして多くのアクターを作成します。
  2. 各アクターが接続を処理し、実際に DB ロジックを処理するようにします。
于 2014-01-22T01:29:46.293 に答える