Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to using "var" for state with actors?

Tags:

scala

akka

actor

I have found myself using vars fairly often with akka actors to maintain state. For example, if I my actor needs to maintain a list of items, I might do something like:

class ListActor extends Actor{
  var xs : List[Int] = List()

  def receive = {
    case x : Int => xs = x :: xs
  }
}

Using the mutable variable seems to go against the spirit of Scala. Alternatively I have used this:

class ListActor2 extends Actor{
  import context._

  def collect_ints(accu : List[Int]) : Receive = {
    case x : Int => become(collect_ints(x :: accu))
  }

  def receive = collect_ints(Nil)
}

I like how this looks more, but do I have to worry about the stack overflowing?

I am aware of the FSM trait and have used that before also, but for some situations it seems like too much.

What is the recommended way of maintaining simple state? Are there other alternatives that I am unaware of?

Also, is it generally a bad sign if I find myself needing mutable variables often? Am I not using the actor model properly?

like image 780
mushroom Avatar asked Sep 15 '13 01:09

mushroom


3 Answers

I don´t see any problem with var for simple state in the actor model.

By design Akka prevents the actor´s state of getting corrupted or locked by concurrent access to the state variables.

As long as you are not exposing your state to other threads with the use of Future for instance, the use of var for simple state should not be a problem.

like image 109
Arnaud Gourlay Avatar answered Nov 19 '22 21:11

Arnaud Gourlay


There are two variants of the become method: one that pushes behavior onto a stack, and one that doesn't. The latter is the default, so you don't have to worry about the behavior stack becoming too large. Using become to manage state in this manner is a perfectly valid use for it.

like image 44
reggert Avatar answered Nov 19 '22 19:11

reggert


The Akka FSM is actually a very compact idiom for maintaining state in an actor system as in this example:

sealed trait State
case object Active extends State

class ListActor extends Actor with FSM[State,List[Int]] {

  startWith(Active,List[Int]())

  when(Active) {
    case Event(x:Int,xs) => stay using x :: xs
  }
}

Having used all the alternatives discussed here, FSM takes my vote for anything that is a shade more complex than trivial.

like image 4
David Weber Avatar answered Nov 19 '22 21:11

David Weber