你应该避免Akka演员的可变状态吗?

时间:2015-06-20 16:13:52

标签: scala akka

目前,我有一个接收一些消息的演员并将此消息的内容保存到可变的类级变量中:

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
    }

}

我认为创建多个receive函数并使用context.become / unbecome来处理不同的状态非常好。 所以在我的情况下,我可以像这样使用receive函数:

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

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

这种方法在我看来非常清楚和好看,但问题是我有其他方法(method1method2)需要这个items1items2变量。我认为唯一可行的解​​决方法是将items1items2传递给method1method2作为函数,但此方法已有2-3个参数,并添加更多对它们的参数将使它们难以阅读(实际上我有两种以上的方法)。

那么,在这种情况下Akka是否有任何模式?或者它很合法'有类级别var(如我的第一个例子)?

2 个答案:

答案 0 :(得分:5)

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

我不知道。

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

在演员内部var是好的,只要你不能从封闭或未来访问它们。

但是,我建议您选择参数解决方案。如果您的参数列表变得很长,您可以考虑将它们分组到case class es。

答案 1 :(得分:3)

具有类级可变状态是绝对可以的 - 但只要您确保不能从receive之外的线程访问它。

此类"外星人"的例子。线程:

  • 创建一个访问可变状态并将其传递给另一个actor的闭包。
  • 使用Akka Scheduler或任何其他方式从这个演员的接收方法中启动一个新线程。

简而言之,不会在演员内部发布新主题,不会将封闭传递给其他演员,你会没事的。