soote: Is there a reason you cannot place this map inside an actor, and have other actors use messages to modify/read it?
Jus12: @soote On second thought, you are right! I will implement it using proper actor model.
soote is, indeed, right: since you're apparently using an actor system, the map should reside in an actor. And in general, when representing mutable state inside an actor, one should use an immutable data structure with a var
instead of a mutable data structure with a val
. The reason for this is to prevent that state from leaking outside the boundaries of the actor. Here is a concrete example using Akka:
case object GetState
case class Add(key: String, value: Int)
case class Remove(key: String)
class MyActor extends Actor {
val state = mutable.Map[String, Int]()
def receive = {
case GetState =>
sender ! state
case Add(k, v) =>
state += (k -> v)
case Remove(k) =>
state -= k
}
}
When the above actor receives a GetState
message, it sends its internal map to the sender. Since the map is mutable, the sender now has the ability to modify that map from outside the actor, thus allowing the possibility of corrupting the actor's state. To prevent this leak, restrict mutability to the actor itself:
class MyActor extends Actor {
var state = Map[String, Int]() // immutable map
def receive = {
case GetState =>
sender ! state
case Add(k, v) =>
state = state + (k -> v)
case Remove(k) =>
state = state - k
}
}
Now MyActor
can safely send its state to other actors because its state is an immutable map.