This blog provides information on first steps to getting started with learning Akka in Java. In this blog we will look at Actor Model, and the problem it tries to solve.

This blog is part of the tutorial series – Learn Akka, in which we will learn about using Akka with Java.

Table of Contents

1.0 Why is Actor Model Required

In this section we will look at common concurrency problem with traditional Object Oriented Model, and and how Actor model tries to solve it. We will also look at some common use cases when we can possibly use the Actor Model.

1.1 Object Oriented Model and Concurrency

You must be familiar with the OOP model, where

  • Objects encapsulate state and behaviour.
  • Communication between objects is done via methods exposed on objects.

The method communication works fine as long as method calls are sequential. However if the method calls concurrent it could lead to stale state of object or to race conditions.

oop-model-concurrency

We generally use locking mechanisms and synchronization to solve this problem of concurrent method access.

However locks leads to blocking and can slow down the application.

Actor Model tries to solve following problems with concurrency

  • Shared Mutable state and and Race conditions
  • Avoiding locks and other blocking operations that can slow down the application.

Actors also follow the following principle

Do not communicate by sharing memory, instead share memory by communicating.

1.2 Some common use cases of Actor model

Actor model can be used in some of the following scenarios

  1. Processing pipeline or Streaming data, where we are reacting based on messages, filtering them out, etc.
  2. Multiple user concurrency and applications with a shared state.
  3. System with high uptime requirements. Actors can be self healing, and restarts are transparent to end users, etc.

1.3 Some drawbacks of using Actors

  1. It’s very easy to create too many actors in the system, and then the tracing of messaging flow between actors becomes very difficult.
  2. Debugging is very difficult, especially in case of remote actors.
  3. Actors are asynchronous, so testing them is difficult.

Top ∆

2.0 Actor Model

2.1 What is an Actor

An actor is essentially nothing more than an object that receives messages and takes actions to handle them. It is decoupled from the source of the message and its only responsibility is to properly recognize the type of message it has received and take action accordingly.

  • Actors are building blocks of Actor model just as Objects are building blocks of OOPs Model. Actors can maintain their own state and encapsulate it. The state of an actor is not exposed to outer world.
  •  Actors communicate through each other via messages. Actor can perform some operation on receiving a message and can change its internal state.
    actors-messaging

    actors-first-program

  • Actors are persistent. Unlike Threads or Futures they do not die when they are completed processing a message. They will continue to exists unless they are told to shutdown, or they stop due to some exceptions.
    actors-lifecycle
  • An actor can only process one message at a time. This helps the actor to avoid race conditions, as all other incoming messages are queued.

Actor-message-dequed

  • One other different feature of Actors are that they can respond to the sender 0 or more number of times. This is unlike other mechanism where almost 1 response can be send back.

2.2 Communication between Actors

  • Communication is asynchronous, i.e. caller actor will continue it processing after sending message to another actor. It will not wait for the other actor to process the message and return results back.
  • The delivery is “Best Effort Delivery”. Most of times it depends on underlying protocol used to send to deliver message. E.g TCP, UDP, etc.
  • At most once delivery of messages. It does not guarantees delivery of messages but makes sure that messages are not duplicated.
  • Ordering of messages is not guaranteed.

If the application is dependent on the order in which an actor is processing a message, then it can still lead to stale state of the actor, since it is not guaranteed which message will be delivered first.

2.3 Address of an Actor

  • The address specifies the physical location under which an Actor can be reached.
    • Local addresses, identified by the ActorSystem’s name,
      e.g. akka://demo-system/user/my-service/worker-1
    • Remote addresses, identified by protocol, host and port.
      e.g. akka.tcp://demo-system@host.example.com:5678/user/my-service/worker-1
  • When we send a message to an actor we don’t care what type of address it is i.e., how we send message to an actor does not depends on whether the actor is in the same process, or residing on some remote machine accessed via TCP protocol.

3.0 Actor Hierarchy

  • Actors are hierarchical in nature
  • Any actor can distribute its work to many child actors.
  • Each actor performs the work and then report back to their parent actors.
  • Parent actors are responsible for supervision of their child actors
actors-hierarchy

A simple analogy  from a real life scenario would be would be a project team, where a manager manages many projects, each project has a project lead, and internally many developers, QA etc.

Each actor is delegating the work to child actors.

actors-hierarchy-2

Let’s look at a proper example where hierarchy would make sense.

We have a streaming pipeline of some data, and there are 3-4 stages of processing to be done on it

  • Each stage of processing could be a child actor – and internally it could itself have a a pool of child workers to do the processing
  • Each stage of workers after doing their processing, pass on the data to the next stage and so on.
actors-hierarchy-2

Top ∆


So to summarize,
  • Actors are hierarchical in nature
  • They can Send and Receive messages asynchronously.
  • Perform some operation and change their local state, when they get a message.

In the next blog of the Learn Akka tutorial series, we will look at Writing your first actor program.