打电话给!!即使在调用者收到回复之后,从一个actor到另一个worker actor的方法似乎也保持了通道的打开状态(即:future已经准备就绪)。
例如,使用!!从一个演员发送11个不同的消息到另一个演员将导致在原始呼叫者的邮箱中显示11个类似于下面的消息,每个消息具有不同的Channel @ xxxx值。
!(scala.actors.Channel @ 11b456f,退出(com.test.app.actor.QueryActor @ 4f7bc2,'正常))
这些消息是否正在等待来自worker的回复,因为原始调用者在它自己调用exit()时发出Exit消息,或者它们是在另一端生成的,并且由于某种原因有上面显示的打印形式?到这时,工人演员已经退出了,所以原来的来电者!!绝对不会收到任何回复。
这种行为是不可取的,因为原始调用actor的邮箱填充了这些退出消息(每次使用的每个频道都有一个!!)。
如何停止?原始呼叫者是否自动“链接”到每个!!上创建的回复频道!调用
答案 0 :(得分:5)
将这些Exit消息发送给原始调用方的原因是调用方将其临时通道(用于接收未来结果)链接到被调用方。特别是,如果频道收到退出信号,则会在该频道上发送退出消息,这会产生类似于您所描述的发送给实际呼叫者的消息(您可以将频道视为消息上的标签)。如果被调用者在服务于将来的消息发送之前终止(在访问未来时抛出异常),则允许(重新)在调用者内部抛出异常。
当前实现的问题是即使未来已经解决,调用者也会收到Exit消息。这显然是应该在Scala Trac上提交的错误。可能的解决方法是,如果未来尚未解决,则仅发送退出消息。在这种情况下,只要使用apply或isSet第一次访问future,就会删除Exit消息。