我正在尝试ask
某个已经在SmallestMailboxPool
远程创建的演员,但我似乎从来没有得到过回应。我的感觉是,这是因为我将消息发送到Router
,但Routee
是响应的演员 - 不知道Akka的确切内部问题,我可以想象答案必须是与发送邮件的位置相同。另一方面,这似乎是如此简陋,以至于我无法想象它会起作用。
我正在使用Play framework 2.3.x和Akka remote 2.3.4
演员设置 我在这些机器上有2台机器和2名演员。我会尽量保持这个例子尽可能简短。
机器A /演员A
实际的问题是在机器A上启动的,我添加了一些println
语句来显示演员地址。代码如下。
class ActorA(remoteActor: ActorRef) extends Actor with ActorLogging {
...
def receive() = {
case a: String => {
println("Remote actor: " + remoteActor)
println("Self: " + self)
// This is where I get a timeout because I never get a reply
Await.result((remoteActor ? a), timeout.duration)
}
}
}
我在机器A上获得的输出如下:
Remote actor: Actor[akka.tcp://application@192.168.0.101:2552/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
Self: Actor[akka://application/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]
请注意,我传递给ActorA的ActorRef
(称为remoteActor
)是我在机器B上创建的val actorRef
(见下文),具有MailboxPool。
机器B /演员B
在机器B上,我有一个在SmallestMailboxPool中创建的Actor B,并从Actor A(通过路由器)收到消息,之后它会回复。
创作如下:
// Creation of the mailbox/Router
val actorRef = Akka.system.actorOf(
SmallestMailboxPool(1).props(
// sourceActor is the actorRef of Actor A, living on machine A
Props(ActorB, sourceActor)
),
name = java.util.UUID.randomUUID.toString
)
println("Mailbox is: " + actorRef)
实际的演员B执行以下操作:
class ActorB(sourceActor: ActorRef) extends Actor with ActorLogging {
println("I am: " + self)
def receive() = {
case a: String => {
println("I got data from " + sender)
println("Sending it back to: " + sourceActor)
sourceActor ! d
}
}
}
我从演员B得到的是以下版画线:
Mailbox is Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3#-1920529606]
I am Actor[akka://application/user/actorB_6f9bac20-2302-4408-9a1b-feece8c20bc3/$a#46262703]
I got data from Actor[akka.tcp://application@192.168.0.132:2552/temp/$e]
I am sending it back to: Actor[akka.tcp://application@192.168.0.132:2552/user/9df0190a-11fb-438c-9124-4869d015fc4d#-867250738]
所以我得不到的是为什么来自ActorA的演员地址在ActorB的一边显示为temp/$e
。还可以看出,ActorB从ActorA获取消息,实际上它将其发送到路由器。然后ActorB正确地尝试回复给ActorA,但它总是会超时 - 这是因为ActorB有一个与路由器/邮箱不同的ActorRef /地址吗?我还尝试发送回sender
而不是参数给定的sourceActor
,但无济于事。
我知道我可以向Mailbox询问其所有Routees并直接向他们发送请求(尚未尝试过),但这违背了MailboxPool的全部目的。 编辑:试过这个,也没办法
修改
整个故事中最奇怪的是,如果我在机器A上创建ActorB
(例如,不是远程),一切正常 - 我可以问路由器的ActorRef
我得到了一个合适的答复。一旦在机器B上创建ActorB
,我就再也没有得到回复。我还试图了解如果我只是tell
ActorB
会发生什么情况并继续ActorA
而不关心结果。然后会发生什么呢?我做从ActorB
获取应该是我对原始提问的回复的消息... ActorB
因此完全有能力发送回{{ 1}}但由于某种原因,Akka不会用它来回复我原来的问题......
答案 0 :(得分:0)
我设法让它发挥作用。事实证明我正在将ActorRef传递给它应该发送给它的ActorB,但是在ActorA的提问时间,似乎Akka制作了一些真正需要从ActorB发送的临时演员(即我可以& #39; t只发送给ActorA的ActorRef,我将其传递给ActorB并存储在前面)。使用sender
对我来说是一个修复。 (虽然我仍然感到困惑,为什么sender
实际上不是我的演员A)。
我的实际用例太复杂了,无法在SO上分享,但我为一些感兴趣的人做了一个小例子(这个问题不会发生 - 一切正常):https://github.com/ErikTromp/AkkaRemoteAskTest。它也使用了Play的Iteratee库,因为这也是我用例的一部分。