如何从演员外部发送Akka,仍然可以使用发件人

时间:2014-08-25 22:22:06

标签: scala akka implicit

我是Scala和Akka的新人。我在Coursera完成了反应式编程课程,我决定在重构期间进行一些重构我发现我的代码因为影响下面代码的行为而无效:

package common

import akka.actor.{ActorRef, ActorSystem, Props, Actor}
import akka.event.LoggingReceive

object NotWorkingActorApp extends App {

case class Start()
case class FromOuter()
case class FromInner()

class InnerProxy {
    def sendInner(innerParam: ActorRef): Unit = {
        innerParam.!(FromOuter)
    }
}

class Outer extends Actor {

    var inner = context.system.actorOf(Props[Inner], name = "inner")
    var proxy = new InnerProxy

    def receive = LoggingReceive {
        case Start => proxy.sendInner(inner)
        case FromInner => println("Finish!")
    }
}

class Inner extends Actor {
    def receive = LoggingReceive {
        case FromOuter => sender.!(FromInner)
    }
}

val system = ActorSystem("InnerOuterSystem")
val outer = system.actorOf(Props[Outer], name = "outer")
outer.!(Start)

}

运行这部分代码后的日志如下所示:

[DEBUG] [08/25/2014 23:37:14.255] [main] [EventStream(akka://InnerOuterSystem)] logger log1-Logging$DefaultLogger started
[DEBUG] [08/25/2014 23:37:14.257] [main] [EventStream(akka://InnerOuterSystem)] Default Loggers started
[DEBUG] [08/25/2014 23:37:14.282] [InnerOuterSystem-akka.actor.default-dispatcher-2] [akka://InnerOuterSystem/user/outer] received handled message Start
[DEBUG] [08/25/2014 23:37:14.284] [InnerOuterSystem-akka.actor.default-dispatcher-2] [akka://InnerOuterSystem/user/inner] received handled message FromOuter
[INFO] [08/25/2014 23:37:14.304] [InnerOuterSystem-akka.actor.default-dispatcher-4] [akka://InnerOuterSystem/deadLetters] Message [common.NotWorkingActorApp$FromInner$] from Actor[akka://InnerOuterSystem/user/inner#-2100738560] to Actor[akka://InnerOuterSystem/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

所以看起来内心无法看到它的发件人。如果方法" sendInner"是在外类,但我想拥有InnerProxy类,并想使用它,因为我喜欢有良好的模块化代码。我该怎么办?

以下版本:

scalaVersion := "2.10.2"

"com.typesafe.akka" %% "akka-actor" % "2.2.3",
"com.typesafe.akka" %% "akka-testkit" % "2.2.3"

1 个答案:

答案 0 :(得分:1)

解决此问题的一种可能方法是重新定义InnerProxy,如下所示:

class InnerProxy {
    def sendInner(innerParam: ActorRef)(implicit senderRef:ActorRef): Unit = {
        innerParam ! FromOuter
    }
}

只要您从一个actor实例内部调用sendInner,那么您总是有一个隐含的ActorRef可用self。结果是,调用sendInner的actor将最终成为任何actor接收消息的sender,然后可以回复。