import akka.actor.{Props, ActorRef, Actor}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
trait AttendantResponsiveness {
val maxResponseTimeMS: Int
def responseDuration = scala.util.Random.nextInt(maxResponseTimeMS).millis
}
object FlightAttendant {
case class GetDrink(drinkname: String)
case class Drink(drinkname: String)
def apply() = new FlightAttendant with AttendantResponsiveness {
val maxResponseTimeMS = 300000
}
}
class FlightAttendant extends Actor {
this: AttendantResponsiveness =>
import FlightAttendant._
def receive = {
case GetDrink(name) =>
context.system.scheduler.scheduleOnce(responseDuration, sender, Drink(name))
}
}
trait AttendantCreationPolicy {
val numberOfAttendants: Int = 8
def createAttendant: Actor = FlightAttendant()
}
trait LeadFlightAttendantProvider {
def newFlightAttendant: Actor = LeadFlightAttendant()
}
object LeadFlightAttendant {
case object GetFlightAttendant
case class Attendant(a: ActorRef)
def apply() = new LeadFlightAttendant with AttendantCreationPolicy
}
class LeadFlightAttendant extends Actor {
//需要混入AttendantCreationPolicy特质
this: AttendantCreationPolicy =>
import LeadFlightAttendant._
override def preStart() {
import scala.collection.JavaConverters._
val attendantNames = context.system.settings.config.getStringList("zzz.akka.avionics.flightcrew.attendantNames").asScala
attendantNames take numberOfAttendants foreach {
i =>
context.actorOf(Props(createAttendant), i)
}
}
def randomAttendant(): ActorRef = {
//获取child
context.children.take(scala.util.Random.nextInt(numberOfAttendants) + 1).last
}
def receive = {
case GetFlightAttendant =>
//派送ActorRef,获取ActorRef
sender ! Attendant(randomAttendant())
case m =>
//转发消息给FlightAttendant即下属
randomAttendant() forward m
}
}
object FlightAttendantPathChecker {
def main(args: Array[String]) {
val system = akka.actor.ActorSystem("PlaneSimulation")
val lead = system.actorOf(Props(new LeadFlightAttendant with AttendantCreationPolicy), "LeadFlightAttendant")
Thread.sleep(2000)
system.shutdown()
}
}
整个程序的层级图解
在application.conf配置akka
akka{
loglevel = DEBUG
actor{
debug{
lifecycle = on
}
}
}
这样我们就可以看到生命周期的log
reference.conf
zzz {
akka {
avionics {
flightcrew {
pilotName = "Harry"
copilotName = "Joan"
leadAttendantName = "Gizelle"
attendantNames = [
"Sally",
"Jimmy",
"Mary",
"Wilhelm",
"Joseph",
"Danielle",
"Marcia",
"Stewart",
"Martin",
"Michelle",
"Jaime"
]
}
}
}
}