Actors & Akka




Purposes?



Damien Katz(CTO in CouchBase):
  • Beginner: "Threads are hard."
  • Intermediate: "Don't fear multithreading."
  • Expert: "Threads are hard."




Agenda



  1. Inroduction
  2. Concurrency problems
  3. Reactive programming
  4. Actor Model
  5. Akka + Some Code
  6. Conclusions

Moore's LAw


MOORE'S LAW

  • Coined in the 1965 paper by Gordon E. Moore
  • The number of transistors is doubling every 18 months
  • Processors manufacturing solves our problems for years
 

but it is dead


  • Chips got big enough, signal is no longer takes cycle time
  • Problems with heat dissipation


World becomes parallel and concurrent

Reactive Programming



In computing, reactive programming is a programming paradigm oriented around data flows and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow.

REACTIVE PROGRAMMING



Parallelism VS COncurrency



Concurrency IS NOT Parallelism


Concurrency is the ability to  run in parallel

Parallelism is really in parallel execution

CONCURRENCY Problem



The main problem of concurrency model is 
MUTABLE  STATE


Lets to be more accurate. Problem is
MUTABLE  SHARED  STATE

And then add some LOCKING mechanism there.

What is a Value?


The VALUE is something that doesn't change

42, "Name",  "07/22/2014", etc.


WHAT IS An Identity?

A stable logical entity 
associated with a series of different
 VALUES over time

What is a state?


Specific IDENTITY has a particular point in time with associated set of VALUES.


If IDENTITY has different VALUES in different timeframes then this IDENTITY has a STATE.

 

Any Problems?

IDENTITY & VALUE should be separate from each other in scope of state. 


Known Solutions


So we need to new level of abstraction

  • Shared State Concurrency (Common sync techniques)
  • Software Transactional Memory (Managed References)
  • Message-Passing Concurrency (Actors Model)
  • Dataflow Concurrency (Dataflow-based processes)

Actors MODEL - History



  • Was found in 1973 by Carl Hewitt
  • First was a theory for concurrency computing
  • Then became a theory ground for Actor implementations
  • Has native implementation in Erlang, Clojure, Scala
  • Has a lot of libraries in other languages

Actors model - Key Principals


  • Actors instead of Objects: Everything is Actor
  • No shared state between Actors
  • Asynchronous immutable message-passing
  • Mailboxes as queue to buffer incoming messages
  • Actor has addresses

When message is coming, Actor can:
  1. send messages to other actors
  2. create new actors
  3. set the logic for next incoming message

Actors Model - Schema


Akka Library




  • Author: Jonas Boner (Terracotta JVM Clusterring, JRockit JVM)
  • Apache V2 License
  • Implementations: Scala, Java
  • JVM Concurrency model: Fork-Join

Akka - Key features



  • 300 bytes per actor
  • Supervisor strategy
  • Set of Actors per set of Threads
  • "Let it crash" behaviour in exceptional situations
  • Distributed cluster environment support

Time for code


public class Worker extends UntypedActor {

    @Override
    public void onReceive(Object message) {
        if (message instanceof Work) {
            BigInteger bigInt = new CalculateFactorial().calculate();
            getSender().tell(new Result(bigInt), getSelf());
        } else
            unhandled(message);
    }

    public static Props createWorker() {
        return Props.create(Worker.class, new ArraySeq<Object>(0));
    }
}

time for code

public class Master extends UntypedActor {
    private long messages = 1000000;
    private ActorRef workerRouter;
    private ArrayList list = new ArrayList();
    public Master() {
        workerRouter = this.getContext().actorOf(Worker.createWorker().withRouter(new RoundRobinRouter(8)), "workerRouter");
    }
    @Override
    public void onReceive(Object message) {
        if (message instanceof Calculate) {
            processMessages();
        } else if (message instanceof Result) {
            list.add(((Result) message).getFactorial());
            if (list.size() == messages) end();
        } else unhandled(message);
    }
    private void processMessages() {
        for (int i = 0; i < messages; i++) workerRouter.tell(new Work(), getSelf());
    }
    private void end() {getContext().system().shutdown();}
}

Time for code



public class Main {

    public static void main(String[] args) {
        new Main().run();
    }

    private void run() {
        ActorSystem system = ActorSystem.create("FactorialSystem");
        ActorRef master = system.actorOf(Master.createMaster(), "master");
        master.tell(new Calculate(), ActorRef.noSender());
    }
} 

Do you wanna See some Scala?



case class Work()
case class Result(factorial: Int)
 

class Worker extends Actor with ActorLogging {
  def receive = {
    case Work => sender ! Result(new CalculateFactorial().calculate())
  }
}

//----------- 
val system = ActorSystem("factorial")
val master = system.actorOf(Props[Master], name = "master")
master ! Work

Actors - Real World usage



  • Yandex.Автомобили
  • Yandex.Недвижимость
  • Facebook chat application
  • RabbitMQ
  • Apache CoucheDB
  • Jabber.org

Conclusions

Pros:

  • Higher abstraction layer
  • Avoid all concurrency problems such as: Race conditions, Deadlocks, Starvations, Live locks
  • Clustering

Cons:

  • Not suitable if we realy have to get shared state
  • Not suitable if we need to have synchronous approach
  • It is not trivial to divide task onto smaller tasks

USEFUL LINKS & RESOURCES


Reactive Programming:
Reactive manifesto

Actor's theory:
Concurrency observation
Actors Model

Akka:
Akka.IO
Let it crash
Akka in Yandex
Made with Slides.com