This is a note for the book Akka in Action.

Fault Tolerance

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.
  • Redundancy
  • Replacement
  • Reboot
  • 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 deadLettersActorRef.

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 OneForOneStrategy or AllForOneStrategy. Strategy types can be Stop, Restart, Resume, or Escalate.

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

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.