17

我发现自己经常使用 vars 和 akka actor 来维护状态。例如,如果我的演员需要维护一个项目列表,我可能会执行以下操作:

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

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

使用可变变量似乎违背了 Scala 的精神。或者我用过这个:

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)
}

我更喜欢它的外观,但我必须担心堆栈溢出吗?

我知道 FSM 特性并且以前也使用过它,但在某些情况下它似乎太多了。

维护简单状态的推荐方法是什么?还有其他我不知道的选择吗?

另外,如果我发现自己经常需要可变变量,这通常是一个坏信号吗?我没有正确使用演员模型吗?

4

3 回答 3

21

我看不到var演员模型中的简单状态有任何问题。

通过设计,Akka 可以防止参与者的状态因并发访问状态变量而被破坏或锁定。

只要您不使用Future 例如将您的状态暴露给其他线程,使用varfor simple state 应该不是问题。

于 2013-09-15T09:03:19.600 回答
7

该方法有两种变体become:一种将行为推送到堆栈上,另一种则不。后者是默认设置,因此您不必担心行为堆栈变得太大。以become这种方式管理状态是一种完全有效的用途。

于 2013-09-15T19:34:32.660 回答
4

Akka FSM实际上是一个非常紧凑的习惯用法,用于在 Actor 系统中维护状态,如下例所示:

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
  }
}

在使用了这里讨论的所有替代方案之后,FSM 投票支持任何比琐碎更复杂的阴影。

于 2013-09-17T12:41:01.737 回答