我打算创建一个自定义路由器,将消息传递给未知数量的动态创建的actor(所有这些)。因此,我需要维护一个类似于here所示想法的“订阅者”列表。但我似乎无法通过上下文切换维护列表。我无法理解为什么创建的可变哈希集在上下文切换后被重置。有办法规避吗?代码:
class myRouter extends Actor {
var subscribers: mutable.HashSet[ActorRef]()
var waitingFor = subscribers
def receive = receiveSubAndRequests
def receiveSubAndRequests: Actor.Receive = {
case RegisterWorker =>
subscribers += sender() //this happens right after initiation
case e: ComputationParams => //say these are guaranteed to come after all have subscribed
subscribers.foreach(s=> s.tell(ComputeIt))//perform some compute. this works!
context.become(receiveResults(e.foo, sender())//pass some state
}
def receiveResults(num: Int, sendTo: ActorRef): Actor.Receive = {
case result: Result =>
waitingFor -= sender() //this works, meaning var was accessed
//other stuff until all results are in
case foo: OtherParams => //say we need to handle and initiate another ComputeIt
// stuff
subscribers.foreach(s => s.tell(ComputeIt)//!!subscribers is empty!!
//other
}
答案 0 :(得分:1)
您的waitingFor
字段只是设置为指向subscribers
的指针,因此当执行第waitingFor -= sender()
行时,发件人将被有效地从subscribers
中移除(正在与指向waitingFor
)相同的可变HashSet。我认为你要找的是在开始计算时初始化waitingFor
:
case e: ComputationParams => //say these are guaranteed to come after all have subscribed
subscribers.foreach(s=> s.tell(ComputeIt))//perform some compute. this works!
waitingFor = new mutable.HashSet(subscribers) // ***
context.become(receiveResults(e.foo, sender())//pass some state
在标记为***
的行上,您(重新)创建waitingFor
为新 HashSet
,初始化为保留所有相同的发件人值subscribers
HashSet
。当你在" receiveResults"中处理case foo: OtherParams =>
时,你也可能需要这样做。状态。