15-214 Notes for chalkboard lecture on Actors in Akka and Scala =============================================================== Learning Goals Understand the Actor model Asynchronous messages delivered to an actor's mailbox Actions an actor can take when responding to a message sending messages creating other actors specifying new behavior for the next message Be able to solve simple problems using actors and pseudocode Describe the advantages of the Actor model for concurrent and distributed computation Learn about some basic Scala constructs and how they simplify Actor programming Sources and References Scala Tutorial for Java Programmers http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html Akka Documentation for Scala http://doc.akka.io/docs/akka/2.3.7/scala.html Akka slides by Jonas Boner (designer of Akka) http://www.slideshare.net/jboner/introducing-akka Carl Hewitt, Peter Bishop, and Richard Steiger. "A Universal Modular Actor Formalism for Artificial Intelligence". IJCAI 2973. Tools The Typesafe Activator for Scala (used for in-class demos) https://typesafe.com/activator Actor model history and motivation History: proposed by Carl Hewitt in 1973 Influenced by Lisp, Simula, and early versions of Smalltalk According to Hewitt, Actors were "motivated by the prospect of highly parallel computing machines consisting of dozens, hundreds or even thousands of independent microprocessors, each with its own local memory and communications processor, communicating via a high-performance communications network." compare: Alan Kay's view of objects as networked computers in Actors, method calls really are asynchronous messages, actors really do act like they are computers with their own threads, and actors can be distributed across a network The Actor model System made up of actors Actors send each other asynchronous messages Messages are queued in a mailbox; Akka: messages from the same sender are enqueued in order (not true in general) Actor may respond to a message by: - sending one or more messages to other actors only those it knows the address of (but see Akka's paths) only form of communication between actors - create one or more new actors Akka: these are children of the creator the parent decides what to do if they fail - specifying the behavior of the actor for the next message Akka: call become, specify a function that case-analyzes on message types In-Lecture Example: a Stack (in pseudo-code) // To create a stack, just instantiate an EmptyStack actor actor EmptyStack(): push(x): let tail = new EmptyStack() // create an actor for the (empty) tail become NonEmptyStack(x, tail) // this actor now is a NonEmptyStack actor NonEmptyStack(top, rest): // think of top and rest as fields of NonEmptyStack pop(): send result(top) to sender // reply to the sender with the top of stack become Forwarder(rest) // forward future messages to the rest of the stack push(x): let tail = new NonEmptyStack(top, rest) // the new tail is just like me become NonEmptyStack(x, tail) // I am a head pointing to the new tail actor Forwarder(stack): push(x): send push(x) to stack // forward push messages unchanged pop(): let req = new PopRequest(stack,sender) // track the sender of this request in a separate actor send pop() to req // have the actor respond to the pop request actor PopRequest(stack, originalSender) pop(): send pop() to stack // forward the pop message on result(x): send result(x) to originalSender // forward the result to the original sender Properties of actors Inherently concurrent typically a set of threads is multiplexed across many actors typically no concurrency within an actor (but there are variants with concurrency) Nonblocking sends are asynchronous Distributed by default (Akka) everything is designed to work in a distributed setting locality is a special case that typically performs better No shared/global state messages should be immutable eases both distribution and concurrency Unreliable message delivery (Akka; other models are reliable) Extremely lightweight Akka: 2.5 million actors per GB of heap Akka : Scala and Java library for actors Greeting example: hello-akka (from the Typesafe Activator) Defining the messages case objects / case classes in Scala Defining the Actor Scala code details { cases } - "environment" construct that defines a function by cases Creating the Actor name Props for configuration (later) factory method returns an ActorRef that way you can't get at the Actor directly - only send it messages through the ActorRef Communicating with the actor ! as an alias for the tell method the sender reference passed explicitly to tell passed implicitly via ! (uses Scala implicits) available inside an actor running it [with Inbox] FSM - Dining Hakker example (from the Typesafe Activator) Remote Samples (from the Typesafe Activator)