Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use singletons in akka scala actor

I have an actor that is delegating calls to a stateful singleton. The singleton is stateful since it is maintaining a map of objects. This singleton object is used just in the actor and in a class (not actor) where I am retrieving one object in this map (so just thread safe read).

class MyActor extends Actor{
  def receive()={
    case ACase => singleton.amethod()  
    case BCase => singleton.bmethod()
     }
 }

val singleton = new MyActorLogic

class MyActorLogic{
 val map:Map[String, Object] = Map()
 def amethod()=//alter the map

 def readMap(value:String) = map(value)    }                

Could there be any side effects/problems? Thanks

like image 837
Matroska Avatar asked Mar 04 '11 02:03

Matroska


2 Answers

Do not do that for any reason in the world. Trust me.

If you need that sort of things use Agent instead, that's what they are good for:

http://doc.akka.io/docs/akka/2.0.4/scala/agents.html

like image 197
Viktor Klang Avatar answered Nov 15 '22 02:11

Viktor Klang


In theory, using MyActorLogic, armed with a simple mutable map, from multiple threads, may lead to concurrent modification exception (when one thread is traversing the map, whilst another's modifying it).

You could do the following to avoid problems :

  1. Put the map into the actor (as a private member). In Akka, you're not working with the Actor instance directly (but rather accessing it through a proxy - ActorRef). In this case, safe access to the map will not only be guaranteed by the actor, that always processes one message at a time - other threads won't be able to access private members even through reflection.
  2. You can make update/retrieval methods of MyActorLogic thread-safe (e.g., making them synchronized)
  3. You can use old-good ConcurrentHashMap
  4. Instead of val map:mutable.Map you can use var map:immutable.Map. Thus, multiple threads accessing map may occasionally work with a stale data, but there will be no concurrent modifications (copy-on-write approach).

Just for the note, true singleton would be:

object MyActorLogic{
 val map:Map[String, Object] = Map()
 ...
like image 3
Vasil Remeniuk Avatar answered Nov 15 '22 02:11

Vasil Remeniuk