在actor.actorSelection上找到“找不到Actor”,其中actorFor有效

时间:2014-04-29 05:52:01

标签: scala akka actor

代码是:

 //      pilot = Await.result(context.actorSelection(s"../$pilotName").resolveOne, 5.seconds)
         pilot = context.actorFor("../" + pilotName)  

actorFor在应用和测试中运作良好 评论的代码在应用程序中工作但在运行测试时失败了akka.actor.ActorNotFound(它看起来存在的演员,我认为超时就足够了),这真的很奇怪。

测试是:

class PilotsSpec extends TestKit(ActorSystem("PilotsSpec",
  ConfigFactory.parseString(PilotsSpec.configStr)))
  with ImplicitSender with WordSpecLike with MustMatchers {
  import PilotsSpec._
  import plane.Plane._

  def nilActor: ActorRef = TestProbe().ref

  val pilotPath = s"/user/TestPilots/$pilotName"
  val copilotPath = s"/user/TestPilots/$copilotName"

  def pilotsReadyToGo(): ActorRef = {
    implicit val timeout = Timeout(5.seconds)

    val a = system.actorOf(Props(
      new IsolatedStopSupervisor with OneForOneStrategyFactory {
        def childrenStart() = {
          context.actorOf(Props[FakePilot], pilotName)
          context.actorOf(Props(new CoPilot(testActor, nilActor, nilActor)), copilotName)
        }
      }), "TestPilots")
    Await.result(a ? IsolatedLifeCycleSupervisor.WaitForStart, 5.seconds)
    system.actorFor(copilotPath) ! Pilots.ReadyToGo
    a
  }

  "CoPilot" should {
    "takecontrol when the Pilotdies" in {
      pilotsReadyToGo()
      // Kill the Pilot
      system.actorFor(pilotPath) ! PoisonPill
      // Sincethe test classis the "Plane" we can
      // expect to see this request
      expectMsg(GiveMeControl)
      // The girl who sent it had better be Mary
      lastSender must be (system.actorFor(copilotPath))
    }
  }

}

我不知道我是否对ActorSelection做错了 我尝试使用onComplete但它仍然无法正常工作并在测试中抛出ActorNotFound异常。

  val f = context.actorSelection("../" + pilotName).resolveOne
  f onComplete {
    case Success(v) => { pilot = v; context.watch(pilot); println("pilot get") }
    case Failure(e) => throw e
  }

有没有人知道为什么actorFor有效,但是actorSelection失败了(完全在测试中)?

然后我将下面的代码添加到测试代码中:

system.actorSelection(pilotPath).resolveOne map {v => println("------pilot:"+v)}
system.actorSelection(copilotPath).resolveOne map {v => println("------copilot:"+v)}
Thread.sleep(1000)   

它工作并打印这些actorRef 然后我尝试将../+pilotName替换为常量字符串pilotPath,但它再次失败(无论context.actorSelection还是context.system.actorSelection
这是例外(片段):

  

仅测试cc.akka.avionics.PilotsSpec
      [info]将1个Scala源编译为G:\ scala_workspace \ akka_test_u7 \ target \ scala-2.10 \ test-classes ...
      [警告]有2个弃用警告;使用-deprecation重新运行以获取详细信息       [警告]发现一个警告
      ------副驾驶:演员[阿卡:// PilotsSpec /用户/ TestPilots /玛丽#962346268]
      ------导频:演员[阿卡:// PilotsSpec /用户/ TestPilots /马克#-320295209]
      ActorSelection [锚点(akka:// PilotsSpec / user / TestPilots / Mary#962346268),路径(/../ Mark)]
      [ERROR] [04/29/2014 15:13:16.080] [PilotsSpec-akka.actor.default-dispatcher-4] [akka.dispatch.Dispatcher]找不到演员:ActorSelection [Ancho       r(akka:// PilotsSpec / user / TestPilots / Mary#962346268),路径(/../ Mark)]
      akka.actor.ActorNotFound:未找到Actor:ActorSelection [Anchor(akka:// PilotsSpec / user / TestPilots / Mary#962346268),Path(/../ Mark)]
              at akka.actor.ActorSelection $$ anonfun $ resolveOne $ 1.apply(ActorSelection.scala:65)
              at akka.actor.ActorSelection $$ anonfun $ resolveOne $ 1.apply(ActorSelection.scala:63)
              在scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
              at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.processBatch $ 1(BatchingExecutor.scala:67)
              at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply $ mcV $ sp(BatchingExecutor.scala:82)
              at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply(BatchingExecutor.scala:59)
              at akka.dispatch.BatchingExecutor $ Batch $$ anonfun $ run $ 1.apply(BatchingExecutor.scala:59)
              在scala.concurrent.BlockContext $ .withBlockContext(BlockContext.scala:72)
              at akka.dispatch.BatchingExecutor $ Batch.run(BatchingExecutor.scala:58)
              at akka.dispatch.ExecutionContexts $ sameThreadExecutionContext $ .unbatchedExecute(Future.scala:74)
              at akka.dispatch.BatchingExecutor $ class.execute(BatchingExecutor.scala:110)

只有actorFor在测试中使用actorSelection注释的其他代码在应用程序中起作用但在测试中失败(很奇怪):

class CoPilot(plane: ActorRef,
  var controls: ActorRef,
  altimeter: ActorRef) extends Actor {
  implicit val timeout = Timeout(1.second)
  implicit val ct = context.dispatcher
  var pilot: ActorRef = context.system.deadLetters
  val pilotName: String = context.system.settings.config.getString("cc.akka.avionics.flightcrew.pilotName")
  val pilotId : Int = 200

  def receive = {
    case ReadyToGo =>
//      fails in test
//      pilot = Await.result(context.actorSelection(s"../$pilotName").resolveOne, 3.seconds)
//      println("get pilot:" + pilot.path + " dead:" + pilot.isTerminated)

//      actorFor works
//      pilot = context.actorFor("../" + pilotName) 
//      context.watch(pilot)
//      autopilot = Await.result(context.actorSelection("../AutoPilot").resolveOne, 100.millis)

//      fails in test
//      val f = context.actorSelection("../" + pilotName).resolveOne  
//      f onComplete {
//        case Success(v) => { pilot = v; context.watch(pilot); println("pilot get") }
//        case Failure(e) => throw e
//      }
        println("-----------"+pilotName)

        // fails in test
        context.actorSelection("../" + pilotName) ! Identify(pilotId) 

    case Terminated(_) =>
      plane ! GiveMeControl
    case Controls(controlSurfaces) =>
      controls = controlSurfaces

    case ActorIdentity(pilotId, Some(ref)) =>
      pilot = ref
      context.watch(pilot)
      println("find copilot:"+pilot)
    case ActorIdentity(pilotId, None) => 
      println("failed to find pilot")
  }
}

0 个答案:

没有答案