我在scala中使用Play Framework。我是scala,akka和play的新手。
这是我的演员系统。我不确定我做得对,但我有两台路由器。演员A为1,演员B为1:
val system = ActorSystem("ActionSystem")
val actorARouter = system.actorOf(Props[ActionParser].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorARouter")
val actorBRouter = system.actorOf(Props[ActionDispatcher].withRouter(
SmallestMailboxRouter(Runtime.getRuntime.availableProcessors())), name = "actorBRouter")
这是我目前的设置: play框架为我提供了一个Controller,它接收一个带有json的http rest调用。每当Controller收到一个休息呼叫时,我都会把json发送给一个路由器,用于演员A.这就是看起来的样子:
(actorARouter ? request.body.asJson.get).map {
case m: controllers.HttpMessages.OK => Ok(m.body)
case m: controllers.HttpMessages.HttpResponse => Status(m.status)(m.body)
}
Actor A然后将json解析为Seq of objects,然后通过ask向Actor B发送它们。Actor B应该最终通过将它们发送给其他actor来处理它们,但是现在只是返回泛型响应。 / p>
ActorA通过将来接收通用响应,然后解析为JSON,然后通过OK响应返回到Controller ......或者至少是应该发生的事情。
发生了什么:
所以发生的事情是控制器发送给ActorA,ActorA发送给ActorB。 ActorB向ActorA发送通用响应。 ActorA将通用响应解析为JSON并尝试执行sender ! OK(json)
但是我在控制台中收到一条消息,说它没有被传递,因为它是一封死信"。当我查看发件人时调试它,发件人是对演员akka://ActionSystem/deadLetters
我的问题:
修改 我发现我可以保存对发件人的引用供以后使用,然后发送给它,这似乎解决了死信问题。但我仍然很不确定这是否是正确的做事方式。感觉就像每次我添加另一层演员时,我的响应时间增加了10毫秒。也许这可能是由于其他因素造成的。
答案 0 :(得分:3)
如果没有查看你的代码,我就无法评论导致死信的原因,从你的编辑我猜你关闭sender()
而不是将其分配给变量并关闭它。
回答你的问题:
forward
代替tell
将原始发件人传递给您的演员。这样,消息流中的最后一个actor就可以生成响应。第一个actor只需要代码来处理响应,而不需要关心生成响应。在那里很好地分离了关注点。如果您需要聚合多个响应以便之后发送单个响应,您还可以使用临时演员,所有其他演员将发送他们的响应,并且知道发送者。临时演员在完成工作后需要停止。self
)