General
Actor Model: OO implementation of large scale concurrent application. It can be hierarchical.
Actor: Objects with encapsulated state and behavior, and communication happens exclusively by exchanging messages.
ActorRef: It represents a single actor during communication.
Actor
Create Actors: extend Actor and implement the receive method. The receive method is a set of case statements for all messages the actor receives and their corresponding behaviors.
Props is a configuration class to specify options for the creation of actors. An instance of it is passed to the actorOf
factory method of ActorSystem
and ActorContext
to create actors.
Actor API:
self
: anActorRef
of the actorsender
: reference sender Actor of the messagecontext
- Overridable life-cycle hooks:
preStart
;postStop
;preRestart
;postRestart
, all returnUnit
.
Message passing:
- The
!
operator (or tell method) to send a one-way asynchronous message (actor ! Message()
) and returnsUnit
immediately. - The
?
operator (or ask method) sends a message and returns aFuture
of possible reply. Usually the Future ispipeTo
an actor to registeronComplete
handler when theFuture
returns. NoteFuture
is a generic type. - Message can be forwarded and sender reference is maintained:
<target> forward <message>
Messages can be defined in sender or receiver. All messages belong to an Actor share a common empty sealed trait, and the messages are declared as case classes so that the fields for message content is automatically generated:
sealed trait All<Actor_name><Description>Message
case class <description>Message(content1: type1, content2: type2, …) extends All<Actor_name><Description>Message
FSM
State * Event -> Action + State (next)
States are defined using the similar manner as messages, but use case object instead:
sealed trait State
case object <description>State extends State
Use startWith(
when(<current_state>) {
case Event(<message_received>, <data>) => {
// do something here
stay using <new_data>
// or
// goto(<new_state>) using <new_data>
}
}
whenUnhandled { … }
statement handles unhandled massages.
onTransition {
case <old_state> -> <new_state> => {
// do something here
}
}
handles operations when state changes.
Stop a FSM by the result state as stop()
. It takes an optional parameter reason, which is one of Normal
(default), Shutdown
, or Failure
. You can use onTermination
handler to execute cleanup:
onTermination {
case StopEvent(FSM.Normal, state, data) => { … }
case StopEvent(FSM.Shutdown, state, data) => { … }
case StopEvent(FSM.Failure(cause), state, data) => { … }
}