# Parallelism

Artūras Šlajus

CTO @  Tiny Lab Productions

arturas.slajus@gmail.com

## A deeper look

Dig 2 holes in the ground.

Each hole takes 10 ticks to dig.

Let's take 3 approaches:

• sequential
• concurrent
• parallel

## Sequential

Yay DOS!

`                                1 1 1 1 1 2                      0 2 4 6 8 0 2 4 6 8 0Hole 1                XXXXXXXXXXContext Switching               XHole 2                           XXXXXXXXXX`

Total ticks: 21

The problem?

Responsiveness.

## Concurrent

Yay modern OSes!

`                                1 1 1 1 1 2 2 2 2                      0 2 4 6 8 0 2 4 6 8 0 2 4 6Hole 1                XXX     XXX     XXX     XContext Switching        X   X   X   X   X   X XHole 2                    XXX     XXX     XXX   X`

Total ticks: 27

The problem?

It takes longer.

## Parallel

Yay multicore CPUs!

`                                1 1 1 1 1 2 2 2 2                      0 2 4 6 8 0 2 4 6 8 0 2 4 6Hole 1                XXXXXXXXXXHole 2                XXXXXXXXXX`

Total ticks: 10

The problem?

It's hard to do.

## Real life

`arturas@razor:~\$ irbirb(main):001:0> a = 0=> 0irb(main):002:0> 10.times { Thread.new { 100.times { a += 1 } } }=> 10irb(main):003:0> a=> 1000`

`arturas@razor:~\$ scalaWelcome to Scala version 2.10.3 (OpenJDK 64-Bit Server VM, Java 1.7.0_51).scala> import java.lang._scala> var a = 0a: Int = 0scala> (0 to 9).foreach { _ => new Thread(new Runnable {   def run = (0 to 99).foreach { _ => a += 1 }}).start }scala> ares1: Int = 565`

## How to fix it

### University edition

`scala> val mutex = new Objectmutex: Object = java.lang.Object@64b51464scala> (0 to 9).foreach { _ => new Thread(new Runnable {   def run = (0 to 99).foreach { _ => mutex.synchronized { a += 1 } }}).start }scala> ares10: Int = 1000`

## Not quite

Simple.

Always lock everything in the same order.

But hard to do.

## Solutions?

Futures, Promises & Execution Contexts

Actor model

## Future is now

Future is a read-many placeholder for a value that might be available some time in the future.

## Futures!

``scala> import concurrent._, ExecutionContext.Implicits.globalscala> val listOfFutures = (0 to 9).map { _ => Future { 100 } }listOfFutures: List[Future[Int]]scala> val futureOfLists = Future.sequence(listOfFutures)futureOfLists: Future[List[Int]]scala> val futureOfSum = futureOfLists.map(_.sum)futureOfSum: Future[Int]scala> futureOfSum.valueres0: Option[scala.util.Try[Int]] = Some(Success(1000))``

## How does it work exactly?

The simple (non-parallel) version

``````trait MyPromise[A] {
def complete(value: A)
def future: MyFuture[A]
def value: Option[A]
}

trait MyFuture[A] {
def onComplete(f: A => Unit)
def value: Option[A]
} ``````

## Implementation

``class MyPromiseFuture[A] extends MyPromise[A] with MyFuture[A] {  private[this] var _value = Option.empty[A]  private[this] var listeners = List.empty[A => Unit]  def future = this  def complete(value: A) = {    if (_value.isDefined)      throw new IllegalStateException("Promise is already completed!")    _value = Some(value)    listeners.foreach(_(value))    listeners = List.empty  }  def value = _value  def onComplete(f: A => Unit) = value.fold(listeners ::= f)(f)}``

## but what's the point?

One of the uses is turning callback style APIs into Future APIs.

`val http: Httpval p = new MyPromiseFuture[Response]http.doRequest(...).onComplete(p.complete)p.future`

## Is it better?

Not for now. But add some magic sauce...

``trait MyFuture[A] {  def map[B](f: A => B): MyFuture[B]  def flatMap[B](f: A => MyFuture[B]): MyFuture[B]  def zip[B](other: MyFuture[B]): MyFuture[(A, B)]}``

## And implement it...

``class MyPromiseFuture[A] extends MyPromise[A] with MyFuture[A] {  def map[B](f: A => B) = {    val p = new MyPromiseFuture[B]    onComplete(f andThen p.complete)    p.future  }  def flatMap[B](f: A => MyFuture[B]) = {    val p = new MyPromiseFuture[B]    onComplete(a => f(a).onComplete(p.complete))    p.future  }  def zip[B](other: MyFuture[B]) = {    val p = new MyPromiseFuture[(A, B)]    onComplete(a => other.value.foreach(b => p.complete(a, b)))    other.onComplete(b => value.foreach(a => p.complete(a, b)))    p.future  }}``

## And you can do this stuff

`val f1 = http.futureRequest(...)val f2 = http.futureRequest(...)val final = f1.zip(f2).flatMap { case (r1, r2) =>   http.futureRequest(r1.dataA, r2.dataB)}.map { r3 => r3.dataC }`

Kind of neat, huh?

## Use it right now

Scala: scala.concurrent.Future

(but really just use Scala futures)

Javascript: https://github.com/FuturesJS/FuturesJS

## lets do actors

Futures are nice and everything.

But we need shared mutable state.

## Real code

``````import akka.actor.{ActorSystem, Props, ActorRef, Actor}object Counter {  case class Inc(by: Int)  case object Current  case class CurrentReply(count: Int)}class Counter(private[this] var count: Int) extends Actor {  def receive = {    case Counter.Inc(by) => count += by    case Counter.Current => sender ! Counter.CurrentReply(count)  }}class Increaser(manager: ActorRef, counter: ActorRef) extends Actor {  (1 to 100).foreach { _ => counter ! Counter.Inc(1) }  counter ! Counter.Current  def receive = { case msg => manager ! msg }}class Manager extends Actor {  val counter = context.actorOf(Props(classOf[Counter], 0), "counter")  val children = (1 to 10).map { i => context.actorOf(    Props(classOf[Increaser], self, counter), s"increaser-\$i"  ) }  def receive = {    case Counter.CurrentReply(count) =>      println(s"\$sender reported count: \$count")  }}object Main {  def main(args: Array[String]) {    val system = ActorSystem("main")    system.actorOf(Props(classOf[Manager]), "manager")    Console.readLine()  }}
``````

## Real Output

`[info] Running Main Actor[akka://main/user/manager/increaser-3#354246439] reported count: 319Actor[akka://main/user/manager/increaser-5#-1720444000] reported count: 365Actor[akka://main/user/manager/increaser-6#-453137600] reported count: 509Actor[akka://main/user/manager/increaser-1#-481790462] reported count: 601Actor[akka://main/user/manager/increaser-2#-2132540929] reported count: 622Actor[akka://main/user/manager/increaser-4#-448697138] reported count: 770Actor[akka://main/user/manager/increaser-7#-1979722102] reported count: 817Actor[akka://main/user/manager/increaser-8#-1507785331] reported count: 856Actor[akka://main/user/manager/increaser-9#-761390070] reported count: 986Actor[akka://main/user/manager/increaser-10#-1851044690] reported count: 1000`

## So that's the basics

• They encapsulate mutable state.
• They run in parallel automatically.
• They are simple to reason about.
• They don't care where they are (e.g. remote machines).
• They handle failure gracefully (actor supervision).
• They can interact with non-actor code (e.g. akka typed actors).

## Where do I get it?

Scala / Java: www.akka.io

Ruby: www.celluloid.io

Python: www.pykka.org

PHP: not yet

## Thank you

Questions?

Artūras Šlajus
CTO @ Tiny Lab Productions
arturas.slajus@gmail.com

https://github.com/arturaz/concurrency-presentation

#### Concurrency & Parallelism

By Artūras Šlajus

• 4,315