【问题标题】:Akka Future Response to a SenderAkka 对发件人的未来响应
【发布时间】:2019-10-25 11:04:16
【问题描述】:

我遇到了以下 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 块的执行以某种方式安排在稍后的时间点发生。

我的理解正确吗?

【问题讨论】:

  • sender 是一个方法,而不是一个验证。

标签: scala akka future


【解决方案1】:
def receive = {
  case Request(data) =>
    future {
      val result = transform(data)
      sender ! Response(result)
    }
}

假设sender ! Response(result) 行在 300 毫秒后执行,恰好在封闭的 Actor 处理另一条消息的同时,我们称之为M。因为 sender 是 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 的状态以响应某些异步计算,您应该从 future 块向自己发送一条消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 2012-09-09
    • 2013-04-30
    相关资源
    最近更新 更多