如何在注入依赖项时检查Actor / ActorRef的类型?

时间:2014-04-02 10:12:13

标签: scala akka

在Akka(scala)中是否有类型检查ActorRef的模式?当我将引用传递给另一个actor时,我想确保它的类型正确。但是,在使用actor的context获取引用时,它总是返回ActorRef,因此我无法真正使用子类来检查它。

下面是一个具体的例子。在Akka中,我通过将ActorRef传递给另一个Actor的构造函数来注入依赖项。请看下面的人为举例:Speaker是使用对Listener的引用构建的。我在伴随对象中创建了一个道具构造函数,如Akka文档所鼓励的那样。

package test
import akka.actor._

object scratchpad {
   object Speaker {
     def apply(listener : ActorRef) : Props = Props(classOf[Speaker],listener)
   }

   class Speaker private(listener : ActorRef) extends Actor {
         override def preStart() = listener ! "knock knock"
   }

   class Listener extends Actor {
     def receive : Receive = {
       case "knock knock" =>
         //received message
     }
   }

   val system = ActorSystem("test")
   val listener = system.actorOf(Props[Listener])
   val speaker = system.actorOf(Speaker(listener))
}

问题是我可以创建另一个actor,比如说DeafMute,然后传递它 - 但是编译器不会捕获它,因为它也是类型ActorRef。有解决这个问题的模式吗?

1 个答案:

答案 0 :(得分:3)

有一些可能性。

对于一个你无法将侦听器传递给构造函数但是使用ActorSelection来查找它。为此,您需要知道路径,但这可能会很棘手,具体取决于您的actor层次结构。我没有用过这么多,但是由于查找是异步的,我希望你需要跳过一些环节以避免计时问题并在尚未初始化时获取消息。另外我认为这可能会对单元测试造成麻烦。

我在其中一个项目中使用的另一种方法是创建一个工厂,根据我想要的Actor类型返回actorrefs。当你考虑演员层次结构和临时演员时,这可能会变得混乱。这个工厂使用依赖注入来创建actor并在内部存储它们以允许查找。在我们的用例中工作得很好,非常适合单元测试,因为你可以模拟工厂并让它轻松返回testProbes。这需要一些工作才能实现,你需要IndirectActorProducer以及更多的东西来使它工作。

除此之外,问题是这是否真的是一个问题。通常你会有“管道”,即连接演员,集中,例如在层次结构的父节点中。如果您以错误的方式连接actor,测试应该捕获它,您也可以激活未处理消息的记录。它需要一些时间来适应它,但没有正确的演员连接的检查并不是那么糟糕,你只需要纪律和一套好的测试。它类似于静态与动态类型的争论。