Scala 中 akka actor 系统中的全局变量

Global variable within akka actor system in Scala

我目前在我的 Scala 代码中使用 akka Actor 系统。我有一个 parent 演员和一个 child 演员。我想做的是在 parent 演员处启动一个列表,让 child 演员:

i) 生成新元素并将它们发送给 parent actor,后者会将它们附加到列表中。 ii) 随时访问列表元素。

我怎样才能实现第二(ii)部分?

您可以选择父级可以回复以公开其内部状态的特定消息。请参阅下面的示例:

  import scala.collection.immutable.Queue

  class Parent extends Actor {
    import Parent._

    // TODO: start children here

    override def receive: Receive = receiveElements(Queue.empty[Element])

    def receiveElements(acc: Queue[Element]): Receive = {
      case e@Element => context.become(receiveElements(acc :+ e))
      case GetElements => sender ! acc
    }
  }

  object Parent {
    case class Element(s: String)
    case object GetElements
  }

请注意,通过将 var queue 保留在父级内部而不是使用 context.become+递归,可以实现相同的行为。

此外,不设计刷新队列的方法可能会导致 OOME。

必须使用消息传递。在两个参与者之间共享任何类型的可变状态都违反了 Akka 提供的所有保证。

或者,您可以在子 actor 和父 actor 之间共享一个 Agent,这将线性化列表更新,同时允许同步读取。

好吧,我设法找到了解决办法。

如果您在父 Actor 中创建一个变量并将其作为构造参数传递给子 Actor,那么如果您不替换它,此变量中的每个更改都是可见的。我会在一个错误的例子之后以正确的例子来解释。

class ParentActor(/*constructors here*/) extends Actor{
   val list =ListBuffer[Int](1,2)
   child = new ChildActor(list //+other constructors)

   list=ListBuffer[Int](1,2,3) // **wrong** child will see list=List(1,2)
   list+=3         // **right**  child will see list=List(1,2,3) as wanted

}

class ChildActor(list : ListBuffer[Int] /*++ otherconstructors here*/) extends Actor{

       list=ListBuffer[Int](1,2,3,4) // **wrong** parent will see list=List(1,2,3)
       list+=4           // **right**  child will see list=List(1,2,3,4) as wanted

}