scala – 问题模式是否适用于Akka IO演员?

假设我有一个能够通过TCP发送和接收消息的IO Actor连接.在我的演员中,我向连接的另一方询问响应:

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

看来,使用此代码,ask将会超时,而包含的actor会在ask模式之外接收原始消息.

你能和Akka IO演员一起使用ask模式吗?如果没有,为什么不呢?

最佳答案 我不太详细地了解这个架构,但这是我如何向自己解释的:

Akka IO连接器actor的问题在于它们不能以请求 – 响应方式工作.如果你考虑一下 – 这是有道理的,因为TCP不是一个请求 – 响应协议. TCP甚至没有消息的概念.从程序员的角度来看,TCP连接只是一对连续的字节流 – 每个方向一个.而已.

Akka IO是网络协议之上的最小角色层,因此它模仿这种行为就不足为奇了.当TCP actor从网络接收一些数据时,它只知道一件事 – 它应该向最初发送Connect消息的actor发送Received消息.就这样.它不知道从网络收到的数据与您之前发送的数据有某种关联.

除此之外,只有在假设当你将消息A发送给某个actor时,才会询问模式是否有效,它将通过将消息B发送给消息A的发送者来响应消息B.正如我们已经知道的,TCP参与者不会这样做 – 它只是将所有内容发送给原始Connect消息的发件人.

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

所以,我最后会得出结论,像这样使用的ask模式对Akka IO不起作用,因为它对于这样的抽象来说太低了.如果您仍然想要它,您需要在Akka IO之上创建自己的抽象层,例如:一些简单的中间actor,涵盖TCP连接器actor并实现请求 – 响应行为.

点赞