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
}
我目前在我的 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
}