WelcomeTo
WelcomeTo

Reputation: 20581

Should you avoid mutable states in Akka Actor?

Currently, I have an actor that receives some message and saves this message's content to mutable class-level variables:

class MyActor extends Actor {

    val items1: Seq[Item] = _ 
    val items2: Seq[Item] = _

    def receive = {
       case Start(items1, items2) => 
         items1= items1
         items2 = items2

       case Result(...) => ...
    } 

    private  def method1(args...) = {
       // do something with items1 and items2
    }

    private  def method2(args...) = {
       // do something with items1 and items2
    }

}

And I read that it's really good to create several receive functions and use context.become / unbecome to handle different states. So in my case I can use receive function like this:

   def running(items1: Seq[Item], items2: Seq[Item]): Receive = {
      case Result(...) => ...
   }

   val waiting: Receive = {
       case Start(items1, items2) =>
          context.become(running(items1, items2))
          start( )
   }

This approach looks to me very clear and nice, BUT the problem is that I have other methods (method1 and method2) which need this items1 and items2 variables. The only possible workaround I think of is to pass items1 and items2 to method1 and method2 as a function, but this method already has 2-3 arguments, and adding more arguments to them will make them difficult to read (actually I have more than 2 methods).

So, is there any pattern in Akka for such cases? Or it's pretty 'legal' to have class-level vars (as in my first example)?

Upvotes: 2

Views: 1447

Answers (2)

Anatoliy Kmetyuk
Anatoliy Kmetyuk

Reputation: 728

It is absolutely OK to have class-level mutable state - but as long as you make sure that it isn't accessed from a thread other than receive's one.

Eamples of such "alien" threads:

  • Creating a closure that accesses the mutable state and passing it to another actor.
  • Launching a new thread from this very actor's receive method - using Akka Scheduler or any other means.

In short, don't launch new threads from within the actor, don't pass closures to other actors, and you'll be fine.

Upvotes: 4

tabdulradi
tabdulradi

Reputation: 7596

So, is there any patterns in Akka for such cases? 

I am not aware of any.

Or it's pretty 'legal' to have class-level vars (as in my first example)?

It is Ok to have var inside actors, as long you don't access them from closures or futures.

However, I'd recommend that you go for the argument solution. If your arguments list became very long, you may consider grouping them in case classes.

Upvotes: 6

Related Questions