所以我有一个基于客户端服务器的程序,客户端将向服务器发送请求,服务器将进行计算和响应。这是通过ask来完成的。
具体而言,客户端将从客户端应用程序收到消息并发送呼叫请求
val response = ask(actorRef, SessionMessage(token, message)).mapTo[ResponseMessage]
服务器会像这样接收
val response = sessionMessage.message match {
case message: message1 =>
ask(actorSet.actor1,message)
case message: message2 =>
ask(actorSet.actor2,message)
其中,actoret实际上是一组不同的演员。
然后我收集结果并发回给发件人
val responseResult = response.mapTo[ResponseMessage]
responseResult pipeTo sender
我遇到的问题是,对于某些请求,数据库查询可能需要一段时间(5-10分钟),当查询完成时,它会发送到死信,我得到一个解离,它无法再次联系并发送到死信。
我认为因为花了这么长时间,发件人会超时(或特别是发件人引用)所以我将发件人引用存储为val,并确认通过这样做我发送者引用丢失了。但是,一旦查询完成并将其传递给正确的发件人,它就会分离。即使是花费一分钟左右的其他查询似乎也没有遇到这个问题,只有持续几分钟的查询解散,我需要重新启动服务器,否则服务器将继续发送死信。
即使我执行onComplete然后发送成功或执行Await.result,同样的问题也会发生,一旦它尝试发送消息(完成后),服务器就会分离并发送给死信。
我非常想知道为什么会这样。
答案 0 :(得分:0)
您遇到的问题是ask
本身有一个超时,它与您在Await.result
中指定的超时分开。 ask
的完整签名是:
def ask (actorRef: ActorRef, message: Any)(implicit timeout: Timeout): Future[Any]
这意味着如果您没有为timeout
手动提供值并且没有自己定义隐式值,则必须通过其中一个导入继承一个。
要延长特定ask
的超时时间,只需使用其中一个调用:
ask(actorRef, SessionMessage(token, message))(15.minutes).mapTo[ResponseMessage]
或者如果这适用于范围内的所有ask
,请声明您自己的implicit
:
implicit val timeout = Timeout(15.minutes)