scala - 询问模式是否适用于 Akka IO Actor ?

标签 scala akka

假设我有一个 IO Actor connection能够通过 TCP 发送和接收消息。在我的 Actor 中,我要求连接的另一端做出回应:

 connection.ask(ByteString("stuff")).collect {
    case Received(response) => log.debug(response.utf8String)
 }

看来,使用此代码, future 的询问超时,而是包含 Actor 在询问模式之外接收原始消息。

你可以对 Akka IO Actor 使用 ask 模式吗?如果不是,为什么不呢?

最佳答案

我不详细了解架构,但这是我向自己解释的方式:

这里 Akka IO 连接器参与者的问题是它们不能以请求-响应方式工作。如果您考虑一下 - 这是有道理的,因为 TCP 不是请求-响应协议(protocol)。 TCP 甚至没有消息的概念。从程序员的角度来看,TCP 连接只是一对连续的字节流——每个方向一个。就是这样。

Akka IO 是网络协议(protocol)之上的最小参与者层,因此它模仿这种行为也就不足为奇了。当 TCP 参与者从网络接收到一些数据时,它只知道一件事——它应该发送一个 Received给最初发送 Connect 的参与者的消息信息。就这样。它不知道它从网络接收到的数据与您之前发送的数据有某种关联。

除此之外,ask模式仅在您发送消息 A 的假设下有效。对于某些 Actor ,它会回复消息 B通过将其准确发送给消息的发件人A .正如我们已经知道的那样,TCP 参与者不会这样做 - 它只是将所有内容发送给原始 Connect 的发送者。信息。

之所以需要这个假设是因为 ask模式实际上创建了某种“幻像”actor,它被设置为使用 ask 发送的消息的发送者。 .这个“幻像”actor 将接收响应并调用在 Future 上注册的所有回调。 .作为旁注 - 请注意,这些回调是完全独立于发送参与者调用的,即它们可能会同时运行!

所以,我最终得出的结论是 ask像这样使用的模式不适用于 Akka IO,因为对于这样的抽象来说,它的级别太低了。如果您仍然想要它,您需要在 Akka IO 之上创建自己的抽象层,例如一些简单的中间参与者,涵盖 TCP 连接参与者并实现请求-响应行为。

关于scala - 询问模式是否适用于 Akka IO Actor ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23569168/

相关文章:

带有play框架的java akka远程集群

scala - 如何阅读这个 Scala 声明?

scala - 比较 sbt 和 Gradle

scala - 如何使用 Scalatra 更改 AsyncResult 的 HTTP 状态代码

java - Play应用程序不执行heroku上的计划任务

java-akka : sending back message to grandparent

Scala/akka 离散事件模拟

scala - 在Scala中,如何在不知道长度的情况下获取从第n个元素到列表末尾的列表切片?

java - 在 Elasticsearch Java API 中使用建议

scala - 玩!框架和 SBT - ebean 模块的问题