开发者

akka: sharing mutable state

I need to have one global variable (singleton) that will change very infrequently. Actually it only changes when the actor restarts, and reinitialize the variable. Since I cannot do this with singleton val in companion object, I have to declare it as a var (mutable).

object UserD开发者_StackOverflow中文版atabase {
    var dbConnection = "" // initializing db connection
}

Many guidelines that I read always go against sharing a mutable state. So I move the variable to class and use message passing to retrieve the variable.

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

Problem is, dbConnection is accessed very frequently by many .. many actors, and continuously sending message will reduce performance (since akka process mailbox one by one).

I don't see how I can do this without sacrificing performance. Any idea?


Perhaps use an Agent instead? http://akka.io/docs/akka/1.2-RC6/scala/agents.html


First of all, have you actually measure/notice performance reduction ? Since messaging is lightweight, perhaps it's fast enough for your application.

Then, a possible solution: If the "global" state is written rarely, but accessed very often, you can choose a push strategy. Every time it changes, the UserDatabase actor will send the updated value to interested actors. You can then use a publish/subscribe approach, rely on the actor register, use a pool of actors, etc.

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


If you don't need to use the variable very often in any case, it might be simpler and more efficient to make it a java.lang.concurrent.atomic.AtomicReference or wrap every access of it in a synchronized block (on the variable). Actors don't always make things easier and safer, just usually.


  1. Create many actors as routees of a RoundRobinRouter.
  2. Make each actor handle a connection and actually handling the DB logic.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜