May 4, 2015 · cloud computing akka akka.net project orleans actors

Akka - A peek into the parallel cloud

1) Introduction

In the past few weeks I decided to enter the distributed parallel computation model that is influenced by Actors and characterized by passing of messages, examining and processing messages. This model maps well to cloud computing as there is no shared state which would cause major concurrency problems. The Actor system came from research work by Carl Hewitt in the 70’s and is quickly gaining popularity recently with many projects coming into the limelight including Microsoft Project Orleans, Akka.Net among others.

Halo is a popular game which is played by many people around the world. It uses a distributed model that enables collection of game data from players, crunching of that data and producing complex aggregates and statistics in relation to the performance each of the gamers.

With so many connected services and the new Internet Of things (IoT) paradigm, we are left with a challenge of manipulating large amounts of data, transmitting larger amounts of data and satisfying the user need of instant feedback/results while battling with latency and inherent complexity of concurrency.

Parallelism and Concurrency are different and I will spare you the semantics.

Quoting Sun's Multithreaded Programming Guide:

Concurrency: A condition that exists when at least two threads are making progress. A more generalized form of parallelism that can include time-slicing as a form of virtual parallelism.

Parallelism: A condition that arises when at least two threads are executing simultaneously.

The focus of my post is not going to be about shared state parallelism or multi-core development that can give you gains by leveraging the multiple processors. These can be implemented using many approaches including threads or thread pools. In the .NET world you would select from many language features including async/await with the Task Parallel Library (TPL) creating Task-based Asynchronous Programming (TAP), PLINQ, Event-based Asynchronous Programming (EAP) or the TPL dataflow library and Reactive Extensions (Rx).

With scalability which requires multiple threading, cores, machines and geolocation we land into distributed applications and the bigger the scale the more we need to understand that failure will happen and we need to embrace it gracefully. The Actor model enables us to adopt the “Let it crash” philosophy knowing that the failed components will be restored to proper state.

2) Akka

This is by no means an exhaustive look into Akka, but an introduction based on my assimilation from a couple of sources. I have found it very interesting and think it is a toolkit I'd like to adopt for cloud applications and most specifically the .NET port.

Akka is a fast growing toolkit that promises easier development of powerful concurrent, fault tolerant, event driven and distributed applications on the JVM. Akka is a message based open-source library with support for Java and Scala and has a .NET /Mono port. It enables creation of lightweight actors that pass messages to each other, create new actors and perform computations.
An important part about this toolkit is integration. There are several parts that make up Akka

  1. Actor model which enables re-integration of data within one machine
  2. Cluster / remoting integrate between subsystems
  3. Http for external systems

With Akka, some of the main things are maximum throughput with acceptable latency and proper scalability to unlimited number of connections, server and client side support and open or composable api. More specifically the Akka-http is focused on fully asynchronous / non blocking, actor friendly, lightweight, composability and is based on spray.io codebase and experience.

Lets look at a simple scala example below

    import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
    import scala.concurrent.duration._

    case object Greet
    case class WhoToGreet(who: String)
    case class Greeting(message: String)

    class Greeter extends Actor {
      var greeting = ""

      def receive = {
    case WhoToGreet(who) => greeting = s"hello, $who"
    case Greet   => sender ! Greeting(greeting) // Send the current greeting back to the sender
      }
    }

    object HelloAkkaScala extends App {

      // Create the 'helloakka' actor system
      val system = ActorSystem("helloakka")

      // Create the 'greeter' actor
      val greeter = system.actorOf(Props[Greeter], "greeter")

      // Create an "actor-in-a-box"
      val inbox = Inbox.create(system)

      // Tell the 'greeter' to change its 'greeting' message
      greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

      // Ask the 'greeter for the latest 'greeting'
      // Reply should go to the "actor-in-a-box"
      inbox.send(greeter, Greet)

      // Wait 5 seconds for the reply with the 'greeting' message
      val Greeting(message1) = inbox.receive(5.seconds)
      println(s"Greeting: $message1")

      // Change the greeting and ask for it again
      greeter.tell(WhoToGreet("typesafe"), ActorRef.noSender)
      inbox.send(greeter, Greet)
      val Greeting(message2) = inbox.receive(5.seconds)
      println(s"Greeting: $message2")

      val greetPrinter = system.actorOf(Props[GreetPrinter])
      // after zero seconds, send a Greet message every second to the greeter with a sender of the greetPrinter
      system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter)

    }

    // prints a greeting
    class GreetPrinter extends Actor {
      def receive = {
    case Greeting(message) => println(message)
      }
    }

We can see that at the beginning we create an Actor system, this will provide a container for the actors we will have in our application. We then create the greeter actor which inherits from the Actor base class, place it in our actor system. We can then send messages to the Actor using the actor system or directly.

Akka also provides reactive streams based API, enabling you to throttle responses to reduce the back pressure where the client tries to download 20Gb of data. The are an abstraction for asynchronous and non-blocking pipeline processing. This enables automatic handling of back pressure. There is a joint effort of Netflix, Twitter, RedHat, Pivotal and TypeSafe.

The .NET example below shows the same thing. The actor system is created and then messages are sent to the actors. The example below is more elegant because of generics. This example is part of the akka.net development repository on https://github.com/akkadotnet/akka.net/

    using System;
    using Akka.Actor;

    namespace HelloAkka
    {
        class Program
        {
            static void Main(string[] args)
            {
                // create a new actor system (a container for actors)
                var system = ActorSystem.Create("MySystem");

                // create actor and get a reference to it.
                // this will be an "ActorRef", which is not a 
                // reference to the actual actor instance
                // but rather a client or proxy to it
                var greeter = system.ActorOf<GreetingActor>("greeter");

                // send a message to the actor
                greeter.Tell(new Greet("World"));

                // prevent the application from exiting before message is handled
                Console.ReadLine();
            }
        }
    }

    public class GreetingActor : ReceiveActor
    {
        public GreetingActor()
        {
            // Tell the actor to respond to the Greet message
            Receive<Greet>(greet => Console.WriteLine("Hello {0}", greet.Who));
        }
    }

    public class Greet
    {
        public string Who { get; private set; }

        public Greet(string who)
        {
            Who = who;
        }
    }

Dowloading the akka.net from github gives you the following.

Naturally some of the examples are in F#. Some of the Akka

Other Benefits of using Akka include

I am watching the Akka.NET project and very optimistic about where it is going. I am working examples and a deeper diver into the internal mechanics of the .NET port and most specifically its work on Microsoft Azure.

Reactive Extensions - http://reactivex.io/
Halo - https://www.halowaypoint.com/en-us/games
Carl Hewitt - http://en.wikipedia.org/wiki/Carl_Hewitt
Orbit Framework - https://github.com/electronicarts/orbit, http://orbit.bioware.com/
Project Orleans - https://github.com/dotnet/orleans

Comments powered by Disqus