Basic introduction into the akka framework.
Declare akka dependency in build.sbt
"com.typesafe.akka" %% "akka-actor" % "2.3.12"Restart SBT to apply changes.
Actors are living in an actor system
import akka.actor._
object HotelLife extends App {
val system = ActorSystem("hotel-life")
Thread.sleep(5000)
system.shutdown()
}Create a basic actor
class Concierge extends Actor {
override def receive = {
case _ => println(s"Good morning, Sir. I am $self")
}
}
val jenkins = system.actorOf(Props[Concierge], "jenkins")An actor lives inside the actor system. It is not accessed directly, instead it is accessed via an ActorRef. An ActorRef provides the method tell to send the actor a message
jenkins.tell("Good morning", ActorRef.noSender)The actor is identified by an URL. The URL identifies an actor even across machines. Actors can also be created inside another actor.
class Guest extends Actor {
override def receive = {
case _ => println(s"Nice to meet you. I am $self")
}
}
val bob = context.actorOf(Props[Guest], "bob")
bob.tell("Good morning", self)Bob is now a child of Jenkins and his URL is a sub path.
An actor can answer to the message sender by sending a message.
sender().tell("Do you have some caviar?", self)The ! operator allows to send a message without a sender
jenkins.tell("Good morning", ActorRef.noSender) ⇔ jenkins ! "Good morning"
bob.tell("Good morning", self) ⇔ bob ! "Good morning"Pass an ActorRef to another arctor
class Concierge extends Actor {
override def receive = {
case "Good morning" => {
println("Someone said good morning to me")
sender() ! "Good morning, Sir"
}
}
}
class Guest(concierge: ActorRef) extends Actor {
override def receive = {
case "Go to lobby" => concierge ! "Good morning"
case message => println(s"Oh he said: $message")
}
}
val bob = system.actorOf(Props(new Guest(jenkins)), "bob)
bob ! "Go to lobby"Sometimes we want to ask an actor for an answer
import akka.pattern.ask
class Guest(concierge: ActorRef) extends Actor {
import ExecutionContext.Implicits.global
implicit val timeout = Timeout(10 seconds)
override def receive = {
case "Go to lobby" => for {
message <- concierge ? "Good morning"
} yield {
println(s"Oh he said: $message")
message
}
}
}