This is a note for the book Akka in Action.
Exception handling doesn’t solve the need to put a fault into its right handler – it mostly used to keep consistent state, not recovery from failures. Adding recovery code in exception handler is not a good idea because often it is a cross-cutting concern. Akka provides the following fault tolerance features in a way of eparation of concerns:
- Fault containment/isolation in a defined structure.
- Component lifecycle
- Suspend with calls saved
Exception handling cannot do it well:
- re-creating/replacing objects and their dependencies is hard.
- ojbects communicates with each other via direct all, not easy to isolate them.
- Fault-recovery code and functional code are tangled up.
Akka provides two separate flows: one for normal logic and one for fault recovery logic. The normal actor code for handling messages only process normal logic without error handling or fault recovery logic. It creashes when there is an exception and its mailbox is suspended until its supervisor decides what to do with the exception. A supervisor decide what to do based on the cause of the crash: restart, resume, stop, and escalate.
An actor is created and automatically started with the
actorOf method in
ActorSystem or an actor’s
ActorContext. There is a
preStart hook. An actor can be stopped using the
stop method or by sending a
PoisonPill message. It has a
postStop hook. A stopped actor is disconnected from its
ActorRef and its
ActorRef is redirected to the
In restart, an instance of an actor is replaced. The old crashed instance uses the
preRestart hook, the new instance uses the
postRestart hook. The default implementation of the
preRestart stops all child actors and calls the
postStop hook. A crashed actor instance in a restart doesn’t send a
Terminated message ot its supervisor. The new replacing actor use the same
ActorRef as the crashed actor. The supervisor decides what should be stored to enable state restoration in restarting.
Any actor can watch an actor and receive
Terminated message. Only parent actor can supervise its child actors. The strategy can be
AllForOneStrategy. Strategy types can be
The default strategy is to stop on initialization and killed exception, restart on all other exceptions. Any
Throwable that isn’t handled by the supervisor strategy will be escalated to the parent of the supervisor.
Futures are used to combine asynchronous functions without states. Actors are great for reactive state management based on messages. Actors live on for a long time and can be supervised and monitored.
A future holds future result and is an asynchronous result handler. After completion, the read-only result can be read many times. Futures are handy for pipelining.