3

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 UserDatabase { 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?

4 Answers 4

3

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

Sign up to request clarification or add additional context in comments.

2 Comments

I just skim through the docs, I think this is what I need. Thanks ! Anyway, I guess, since akka persistence is deprecated, many developers are struggling to find the best design pattern for akka DAO to some popular database. Would be glad if there's tutorial to do so.
I recommend doing EventSourcing
2

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

1 Comment

Yes, there is reduction. I made simple concurrent test using 10000 Future and the result is noticeable. Publisher-subscriber pattern will involve keeping lists of subscribers. I would say this is not scalable for my need, since most of my actors are short lived (hence register-deregister a lot). I guess the point is that I dont need serial read / synchronize that actor's provide. I need concurrent read, serial write.
1

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.

3 Comments

If you want high throughput, synchronized may not be a good solution. Atomics are OK as are explicit locks: ibm.com/developerworks/java/library/j-jtp11234
@paradigmatic - I specified a low-contention case. If there's high contention, I agree that atomics or ReentrantReadWriteLocks (or broadcasting the value to the actors that need it) are better.
OP specifically asked for high contention case.
0
  1. Create many actors as routees of a RoundRobinRouter.
  2. Make each actor handle a connection and actually handling the DB logic.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.