The Artima Developer Community
Sponsored Link

Akka Concurrency Forum
Minor inconsistency in Section 7.4

6 replies on 1 page. Most recent reply: Mar 3, 2013 4:18 PM by Andreas Gies

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 6 replies on 1 page
Shing Hing Man

Posts: 9
Nickname: 84423
Registered: Oct, 2012

Minor inconsistency in Section 7.4 Posted: Nov 10, 2012 10:29 AM
Reply to this message Reply
Advertisement
I have noticed the following minor inconsistencies in Section 7.4.

1) In the receive method of the class Pilot, the case class
Controls(controlSurfaces) is not defined.

I think object Pilot should include
case class Controls(controlSurface:ActorRef)

Also, in object Pilot,
case object RelinquishControl
is not used in Chapter 7.

2) In trait PilotProvider and class Plane, there are references to class AutoPilot. But class AutoPilot is not defined.

3) The trait PilotProvider is not used in Chapter 7.


Dan Luu

Posts: 27
Nickname: amitra
Registered: Feb, 2013

Re: Minor inconsistency in Section 7.4 Posted: Feb 19, 2013 5:58 PM
Reply to this message Reply
I also ran into this in the recently released (2/15/13) V2 pre-print.

I worked around it by using case RelinquishControl in the receive method, but I'm not sure what the original intent was.

Derek Wyatt

Posts: 64
Nickname: dwyatt
Registered: Oct, 2012

Re: Minor inconsistency in Section 7.4 Posted: Feb 19, 2013 9:09 PM
Reply to this message Reply
> I have noticed the following minor inconsistencies in
> Section 7.4.
>
> 1) In the receive method of the class Pilot, the case
> class
> Controls(controlSurfaces) is not defined.
>
> I think object Pilot should include
> case class Controls(controlSurface:ActorRef)
>
> Also, in object Pilot,
> case object RelinquishControl
> is not used in Chapter 7.

Damn. This is defined on the Plane companion object. At this point in the book it should look like this:

object Plane {
// Returns the control surface to the Actor that
// asks for them
case object GiveMeControl
case class Controls(controls: ActorRef)

// Eases creation of the Plane
def apply() = new Plane with AltimeterProvider
with PilotProvider
with LeadFlightAttendantProvider
}

I'll have to fix that. Thanks.

>
> 2) In trait PilotProvider and class Plane, there are
> references to class AutoPilot. But class AutoPilot is not
> defined.

Yeah that one is actually meant to be done by you... it's a simple hiccup. I'm getting the impression from people, though, that it's not cool.

>
> 3) The trait PilotProvider is not used in Chapter 7.

As you can see above, it should be, but I've messed something up in here somewhere.

The whole Plane.scala file should be, at this point, the following:


package zzz.akka.avionics

import akka.actor.{Actor, ActorRef, Props, ActorLogging}
import akka.actor.SupervisorStrategy._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._

object Plane {
// Returns the control surface to the Actor that
// asks for them
case object GiveMeControl
case class Controls(controls: ActorRef)

// Eases creation of the Plane
def apply() = new Plane with AltimeterProvider
with PilotProvider
with LeadFlightAttendantProvider
}

// We want the Plane to own the Altimeter and we're going to
// do that by passing in a specific factory we can use to
// build the Altimeter
class Plane extends Actor with ActorLogging {
this: AltimeterProvider
with PilotProvider
with LeadFlightAttendantProvider =>
import IsolatedLifeCycleSupervisor._
import Altimeter._
import Plane._

// There's going to be a couple of asks below and
// a timeout is necessary for that.
implicit val askTimeout = Timeout(1.second)
val config = context.system.settings.config

// We're going to want to remember the names of our crew
val cfgstr = "zzz.akka.avionics.flightcrew"
val pilotName = config.getString(s"$cfgstr.pilotName")
val copilotName = config.getString(s"$cfgstr.copilotName")
val attendantName = config.getString(
s"$cfgstr.leadAttendantName")

// Helps us look up Actors within the "Pilots" Supervisor
def actorForPilots(name: String) =
context.actorFor("Pilots/" + name)
// Helps us look up Actors within the "Equipment" Supervisor
def actorForControls(name: String) =
context.actorFor("Equipment/" + name)

def startPeople() {
val plane = self
// Note how we depend on the Actor structure beneath
// us here by using actorFor(). This should be
// resilient to change, since we'll probably be the
// ones making the changes
val controls = actorForControls("ControlSurfaces")
val autopilot = actorForControls("AutoPilot")
val altimeter = actorForControls("Altimeter")
val people = context.actorOf(
Props(new IsolatedStopSupervisor
with OneForOneStrategyFactory {
def childStarter() {
// These children get implicitly added
// to the hierarchy
context.actorOf(
Props(newCoPilot(plane, autopilot, altimeter)),
copilotName)
context.actorOf(
Props(newPilot(plane, autopilot,
controls, altimeter)),
pilotName)
}
}), "Pilots")
// Use the default strategy here, which
// restarts indefinitely
context.actorOf(Props(newFlightAttendant), attendantName)
Await.result(people ? WaitForStart, 1.second)
}

// Equipment started here using a simple strategy that
// resumes children
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)
}

override def preStart() {
import EventSource.RegisterListener
import Pilots.ReadyToGo
// Get our children going. Order is important here.
startEquipment()
startPeople()
// Bootstrap the system
actorForControls("Altimeter") ! RegisterListener(self)
actorForPilots(pilotName) ! ReadyToGo
actorForPilots(copilotName) ! ReadyToGo
}

def receive = {
case AltitudeUpdate(altitude) =>
log info(s"Altitude is now: $altitude")
case GiveMeControl =>
sender ! Controls(actorForControls("ControlSurfaces"))
}
}

Dan Luu

Posts: 27
Nickname: amitra
Registered: Feb, 2013

Re: Minor inconsistency in Section 7.4 Posted: Feb 20, 2013 11:25 AM
Reply to this message Reply
In case it helps you debug the text, I just finished chapter 7, and here's what I have for Plane.scala

https://github.com/danluu/akka-concurrency-wyatt/blob/1c6e78d39cb132fe2c955e0210432d5048f59939/src/main/scala/Plane.scala


package zzz.akka.avionics

import akka.actor.{Props, Actor, ActorLogging}

object Plane{
case object GiveMeControl
}

class Plane extends Actor with ActorLogging{
import Altimeter._
import Plane._
import EventSource._

val altimeter = context.actorOf(Props(Altimeter()), "Altimeter")
val controls = context.actorOf(Props(new ControlSurfaces(altimeter)))

override def preStart() {
altimeter ! RegisterListener(self)
}

def receive = {
case GiveMeControl =>
log.info("Plane giving control")
sender ! controls
case AltitudeUpdate(altitude) =>
log.info("Altitude is now: " + altitude)
}

}

Dan Luu

Posts: 27
Nickname: amitra
Registered: Feb, 2013

Re: Minor inconsistency in Section 7.4 Posted: Feb 21, 2013 6:42 AM
Reply to this message Reply
After working through chapter 8, I think your code above is actually the state of Plane.scala after chapter 8? At least in how the chapters are numbered in the V2 pre-print.

Derek Wyatt

Posts: 64
Nickname: dwyatt
Registered: Oct, 2012

Re: Minor inconsistency in Section 7.4 Posted: Feb 22, 2013 5:49 AM
Reply to this message Reply
You're right. Sorry about that. I've got 22 branches in this book and a bunch of different copies I need to look at :)


package zzz.akka.avionics

import akka.actor.{Actor, ActorRef, Props, ActorLogging}

object Plane {
// Returns the control surface to the Actor that
// asks for them
case object GiveMeControl
case class Controls(controls: ActorRef)
}

// We want the Plane to own the Altimeter and we're going to
// do that by passing in a specific factory we can use to
// build the Altimeter
class Plane extends Actor with ActorLogging {
import Altimeter._
import Plane._

val cfgstr = "zzz.akka.avionics.flightcrew"
val altimeter = context.actorOf(
Props(Altimeter()), "Altimeter")
val controls = context.actorOf(
Props(new ControlSurfaces(altimeter)), "ControlSurfaces")
val config = context.system.settings.config
val pilot = context.actorOf(Props[Pilot],
config.getString(s"$cfgstr.pilotName"))
val copilot = context.actorOf(Props[CoPilot],
config.getString(s"$cfgstr.copilotName"))
val autopilot = context.actorOf(
Props[AutoPilot], "AutoPilot")
val flightAttendant = context.actorOf(
Props(LeadFlightAttendant()),
config.getString(s"$cfgstr.leadAttendantName"))

override def preStart() {
// Register ourself with the Altimeter to receive updates
// on our altitude
altimeter ! EventSource.RegisterListener(self)
List(pilot, copilot) foreach { _ ! Pilots.ReadyToGo }
}

def receive = {
case AltitudeUpdate(altitude) =>
log info(s"Altitude is now: $altitude")
case GiveMeControl =>
sender ! Controls(controls)
}
}

Andreas Gies

Posts: 15
Nickname: 84653
Registered: Nov, 2012

Re: Minor inconsistency in Section 7.4 Posted: Mar 3, 2013 4:18 PM
Reply to this message Reply
Hi again,

a strange character taking a computer book to a vacation and actually reading it ;)

I nearly agree with your version of the plane. You have introduced that Providers for the Flight Attendant and the Pilots in chapter 7, so i think it makes sense to use them here ?

Here is my version after chapter 7:

package zzz.akka.avionics

import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.actor.ActorRef

object Plane {
case object GiveMeControl
case class Controls(controls: ActorRef)

def apply() = new Plane with PilotProvider with LeadFlightAttendantProvider
}

class Plane extends Actor with ActorLogging { this: PilotProvider with LeadFlightAttendantProvider =>

import EventSource._
import Altimeter._
import Plane._

val cfgstr = "zzz.akka.avionics.flightcrew"
val config = context.system.settings.config
val altimeter = context.actorOf(Props(Altimeter()), "Altimeter")
val controls = context.actorOf(Props(new ControlSurfaces(altimeter)), "Controls")
val autopilot = context.actorOf(Props(createAutopilot), "AutoPilot")
val pilot = context.actorOf(Props(createPilot), config.getString(s"$cfgstr.pilotName"))
val copilot = context.actorOf(Props(createCopilot), config.getString(s"$cfgstr.copilotName"))
val flightAttendant = context.actorOf(Props(createFlightAttendant), config.getString(s"$cfgstr.leadAttendantName"))

override def preStart() {
altimeter ! RegisterListener(self)
List(pilot, copilot) foreach { _ ! Pilots.ReadyToGo }
}

def receive = {
case AltitudeUpdate(altitude) =>
log.info(s"The altitude is now [$altitude]")
case GiveMeControl =>
log.info("Plane giving control.")
sender ! Controls(controls)
}
}

To make that work, I have created a place holder for the AutoPilot, perhaps coming back to it at a later stage, for now:

package zzz.akka.avionics

import akka.actor.Actor

class AutoPilot extends Actor {

def receive = Actor.emptyBehavior

}

Best regards
Andreas

Flat View: This topic has 6 replies on 1 page
Topic: Ch 13, Telnet server example (Success(...) and Failure(_)) Previous Topic   Next Topic Topic: Chapter 8 :  Runtime error when using a concrete IsolatedResumeSupervisor


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us