首页 文章

Akka remoting - 要求routee不回答

提问于
浏览
1

我正在尝试 ask 某个已经在 SmallestMailboxPool 远程创建的演员,但我似乎从来没有得到过回应 . 我的感觉是,这是因为我将消息发送到 Router ,但 Routee 是响应的演员 - 不知道Akka的确切内部工作 .

我正在使用Play framework 2.3.x和Akka remote 2.3.4

Actor Setup 我在这些机器上有两台机器,有两个演员 . 我会尽量保持这个例子尽可能简短 .

机器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]

请注意, ActorRef 我传递给ActorA(名为 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)

实际的Actor 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的全部目的 . EDIT :试过这个,也没用

EDIT:

这整个故事中最奇怪的是,如果我在机器A上创建 ActorB (例如,不是远程),一切正常 - 我可以问路由器的 ActorRef 并得到一个正确的答复 . 一旦在机器B上创建 ActorB ,我就再也没有得到回复 . 我也试着看看如果我只是 tell ActorB 会发生什么,并继续在 ActorA 而不关心结果 . 接下来发生的事情是我 doActorB 获取的信息应该是我对原始问题的回复... ActorB 因此完全有能力发送回 ActorA 但由于某种原因,Akka不会将其用作对我的回复原问...

1 回答

  • 0

    我设法让它工作 . 事实证明我正在将ActorRef传递给它应该发送给它的ActorB,但是在ActorA的提问时间,似乎Akka制作了一些真正需要从ActorB发送的临时演员(即我可以我只是发送给ActorA的ActorRef,我将它传递给ActorB并存储在前面) . 使用 sender 对我来说是一个修复 . (虽然我仍然感到困惑,为什么 sender 实际上不是我的演员A) .

    我的实际用例太复杂了,无法在SO上分享,但我为一些感兴趣的人做了一个小例子(这个问题没有发生 - 一切正常):https://github.com/ErikTromp/AkkaRemoteAskTest . 它也使用Play的Iteratee库,因为这也是我的用例的一部分 .

相关问题