我遇到了以下SIP:
http://docs.scala-lang.org/sips/pending/spores.html
在我阅读时,我遇到了这个例子:
def receive = {
case Request(data) =>
future {
val result = transform(data)
sender ! Response(result)
}
}
该文章中有以下描述:
> Capturing sender in the above example is problematic, since it does not return a stable value. It is possible that the future’s body
> is executed at a time when the actor has started processing the next
> Request message which could be originating from a different actor. As
> a result, the Response message of the future might be sent to the
> wrong receiver.
我不完全了解这一行"在上面的例子中捕获发件人是有问题的...."是不是每次请求Actor(请求(数据))都会创建Future块的情况?
创建Future块是同步的,这意味着当时已知发送者引用。只是那个Future块的执行以某种方式计划在稍后的时间点发生。
我的理解是否正确?
答案 0 :(得分:2)
def receive = {
case Request(data) =>
future {
val result = transform(data)
sender ! Response(result)
}
}
想象一下,行sender ! Response(result)
在300毫秒后执行,与封闭的演员正在处理另一条消息的同时,我们称之为M
。因为发送者是def而不是val,所以每次使用时都会对其进行评估。这意味着,在未来你有M
消息的发送者!您没有回复创建Future
的原始邮件的发件人,而是回复给其他人。要缓解此问题,您需要在创建Future
时关闭sender()def的值。将原始代码与此进行比较:
def receive = {
case Request(data) =>
val client = sender()
future {
val result = transform(data)
client ! Response(result)
}
}
你记得原始发件人,所以一切都是正确的。
最重要的是从不执行任何依赖于时间的方法(如sender
)或以异步方式更改actor的状态。如果您需要更改actor的状态以响应某些异步计算,您应该从future
块发送一条消息。