On page 201 (AkkaConcurrencyPrePrintV2.pdf ), in method StartEquiment, an anonymous implementation of IsolatedResumeSupervisor is used.
def startEquipment() { val controls = context.actorOf( Props(new IsolatedResumeSupervisor with OneForOneStrategyFactory { def childStarter() { val alt = context.actorOf( Props(newAltimeter), "Altimeter") // These children get implicitly added to the hierarchy context.actorOf(Props(newAutopilot), "AutoPilot") context.actorOf(Props(new ControlSurfaces(alt)),"ControlSurfaces") } }), "Equipment")
Await.result(controls ? WaitForStart, 1.second) }
Instead of using an anonymous class, I created a concrete class :
class IsolatedResumeSupervisorImpl(altIn: Altimeter) extends IsolatedResumeSupervisor with OneForOneStrategyFactory {
def childStarter() { val alt = context.actorOf( Props(altIn), "Altimeter") // These children get implicitly added to the hierarchy context.actorOf(Props(newAutopilot), "AutoPilot") context.actorOf(Props(new ControlSurfaces(alt)),"ControlSurfaces") } }
Then set val controls= context.actorOf(Props(new IsolatedResumeSupervisorImpl(newAltimeter)), "Equipment")
With the above change, I get the following runtime error :
[ERROR] [03/01/2013 11:49:27.970] [PlaneSimulation-akka.actor.default-dispatcher-3] [akka://PlaneSimulation/user/Plane/Controls] error while processing Create(550190450) f0f88567-ed52-4fbd-bdfc-3d2a588268d3akka.actor.ActorInitializ ationException: exception during creation at akka.actor.ActorInitializationException$.apply(Actor.scala:169) at akka.actor.ActorCell.create(ActorCell.scala:496) at akka.actor.ActorCell.systemInvoke(ActorCell.scala:351) at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:256) at akka.dispatch.Mailbox.run(Mailbox.scala:211) at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDi spatcher.scala:502) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:10 4) Caused by: e067abb3-c2f6-47c9-ac18-3fdc19e7eb23akka.actor.ActorInitializationException: You cannot create an instance of [net.sf.akka.avionics.supervisor.IsolatedResumeSupervisorImpl] explicitly using the constructor (new). You have to use one of the factory methods to create a new actor. Either use: 'val actor = context.actorOf(Props[MyActor])' (to create a supervised child actor from within an actor), or 'val actor = system.actorOf(Props(new MyActor(..)))' (to create a top level actor from the ActorSystem) at akka.actor.ActorInitializationException$.apply(Actor.scala:170) at akka.actor.Actor$class.$init$(Actor.scala:381) at net.sf.akka.avionics.supervisor.IsolatedResumeSupervisor.<init>(IsolatedR esumeSupervisor.scala:10) at net.sf.akka.avionics.supervisor.IsolatedResumeSupervisorImpl.<init>(Isola tedResumeSupervisorImp.scala:11) at net.sf.akka.avionics.Plane$$anonfun$2.apply(Plane.scala:114)
I have seemed context.actorOf(Props(new MyActor())) works elsewhere, and wondering why it doe not work in the above.
class IsolatedResumeSupervisorImpl(altIn: Altimeter) extends IsolatedResumeSupervisor with OneForOneStrategyFactory
You're not passing in an ActorRef to an Altimeter, but an Altimeter proper. You need to either pass in an ActorRef, or pass in an Altimeter factory that you can then create the ActorRef with later, and doing the factory thing is probably what you're looking for:
class IsolatedResumeSupervisorImpl(altIn: => Actor) extends IsolatedResumeSupervisor with OneForOneStrategyFactory
If you want to use a specific Altimeter (i.e. => Altimeter) then you need to change the return types of Altimeter.apply() and AltimeterProvider.newAltimeter.
Awesome work - trying to go beyond what's written up, even in small ways, is a fantastic way to solidify the learning!