gpt4 book ai didi

scala - 通过将带有参数的方法传递给 "become"来更改 Akka actor 状态

转载 作者:行者123 更新时间:2023-12-04 04:11:41 24 4
gpt4 key购买 nike

我在我的 Akka actor 中使用 become 时遇到了一些问题。基本上,我的 Actor 有这样的结构:

// This is where I store information received by the actor
// In my real application it has more fields, though.
case class Information(list:List[AnyRef]) {
def received(x:AnyRef) = {
Information(list :+ x)
}
}

class MyActor extends Actor {

// Initial receive block that simply waits for a "start" signal
def receive = {
case Start => {
become(waiting(Information(List())))
}
}

// The main waiting state. In my real application, I have multiple of
// these which all have a parameter of type "Information"
def waiting(info:Information):Receive = {

// If a certain amount of messages was received, I decide what action
// to take next.
if(someCondition) {
decideNextState(x)
}

return {
case Bar(x) => {
//
// !!! Problem occurs here !!!
//
// This is where the problem occurs, apparently. After a decision has been
// made, (i.e. decideNextState was invoked), the info list should've been
// cleared. But when I check the size of the info list here, after a decision
// has been made, it appears to still contain all the messages received
// earlier.
//
become(waiting(info received x))
}
}
}

def decideNextState(info:Information) {
// Some logic, then the received information list is cleared and
// we enter a new state.
become(waiting((Information(List())))
}
}

抱歉,代码片段太长了,但我真的不能让它更小。

出现问题的部分在评论中标出。我将一个参数传递给返回 Receive 部分函数的方法,然后将其传递给 become 方法。但是,创建的部分函数似乎以某种方式保留了先前调用的状态。我发现这个问题有点难以解释,但我已尽力在代码的注释中做到这一点,所以请阅读这些内容,我会回答任何不清楚的地方。

最佳答案

你的逻辑有点复杂,但我会分析一下可能是什么问题:

如果 someCondition 为真,那么您的 actor 将进入一个状态,我们称其为 S1,其特征是一个值 Information(List())。然后你返回(顺便说一下,除非绝对必要,否则避免使用 return)一个接收方法,它将把你的 actor 置于状态 S2,其特征是列表信息(somePreviousList :+ x)。所以在这一点上,你的状态堆栈上有 S1。但是,当您收到 Bar(x) 消息时,状态 S2 将被推送,从而覆盖 S1,您实际上会转换到一个状态,该状态的特征是具有旧值的信息 + 您的新 x.

或者类似的东西,你的 actor 中的递归有点令人着迷。

但我会建议重写该代码,因为看起来发生变化的状态是某种类型的信息,而您正在使用 Akka 的 actor 状态转换来操纵此状态,这根本不是执行此操作的最佳工具。 becomeunbecome 旨在用于从 actor 的行为 的不同状态转换。也就是说,一个 Actor 可以随时有不同的行为,您可以使用 becomeunbecome 在这些行为之间进行更改。

为什么不做这样的事情呢?

class MyActor extends Actor {

private var info = Information(List.empty)

def receive = {
case Start => info = Information(List()) //a bit redundant, but it's just to match 1:1 with your code
case Bar(x) => {
if (someCondition) {
info = Information(List.empty)
}
info = info received x
}
}

}

我可能没有捕捉到你的全部想法,但你明白了。

关于scala - 通过将带有参数的方法传递给 "become"来更改 Akka actor 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13400300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com