53
MADRID · NOV 27-28 · 2015 Scala Programming @ Madrid Akka voló sobre el nido del Future Javier Santos David Vallejo

Codemotion 2015 - Akka voló sobre el nido del future

Embed Size (px)

Citation preview

Page 1: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka voló sobre el nido del FutureJavier SantosDavid Vallejo

Page 2: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

About us

David Vallejo @dvnavarro

« It’s not a bug – it’s an undocumented feature.» Anonymous

Javier Santos @jpaniego

«Hay dos formas de programar sin errores; solo la tercera funciona»

Alan J Perlis

Page 3: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Introduction: A functional world

● Purely functional: whole world could be implemented in a single functional line

● Functional features○ Robust○ Debuggable○ Predictable○ Pluggable

Page 4: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Introduction: A functional world

● Example

type Context = (Input,Output,Error)type Action = Context => (Context,Event)

def main(

actions: Iterable[Action], context: Context):(Context,Seq[Event]) = {

((context,Seq.empty[Event]) /: actions) {

case ((context,events),action) =>

action.apply(context) match {

case (context,event) => (context, events :+ event)

}

}

}

Page 5: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 6: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Introduction: A functional world

● Problem? World actions are not precalculated. What happens to I/O?

● World can be considered as○ asynchronous: Things may happen at same time○ reactive: Things may happen due to

■ actions: that trigger …■ ...events: action consequences.

Page 7: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Introduction: Runnable & Callable

● java.lang.Runnable

trait Runnable {

def run(): Unit

}

● java.util.concurrent.Callable

trait Callable[V] {

def call(): V

}

Page 8: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Introduction: Threads

● Scala’s concurrency model is built on Java’s

● java.lang.Thread

val myThread = new Thread(new Runnable {

def run(){

println(“hi”)

}

}

myThread.start()

● Thread improvements (ExecutorService ~ Thread pool)● Anyway, Threads abstraction level is too low

Page 9: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

What about Scala and threads?

Page 10: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Overview

● By default, non-blocking operations

● They will hold a T value at some point

● So a future may be uncompleted(it has no value yet) or completed

● Completion will be treated as a scala.util.Try valueIt will have two possible values:○ Success(t: T)○ Failure(t: Throwable)

Page 11: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Overview

● Future example

import scala.concurrent._

import ExecutionContext.Implicits.global

val firstPrimeNumbers: Future[List[Int]] = Future {

List(1,2,3,5,7,11,13)

//what if 'calculateFirstPrimeNumbers(100000000)'…

}

res0: Future[List[Int]]

Page 12: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Overview

● Failing Future example

import scala.concurrent._

import ExecutionContext.Implicits.global

val thisWillFail: Future[Int] = Future(2 / 0)

res0: Future[Int]

Page 13: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: ExecutionContext

● A future, once it’s completed, it never changes of value

● An ExecutionContext ○ executes tasks submitted to them.○ They can be seen as thread pools.○ Most of future ops require an implicit

ExecutionContext.

Page 14: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Expecting results

● Expecting results.

○ Blocker way (discouraged but sometimes mandatory).

○ Non-blocker way: using callbacks

Page 15: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Blocking - Await

● Blocking: Await.result / Await.ready

import scala.concurrent._import scala.concurrent.duration._import scala.concurrent.ExecutionContext.Implicits.global

val f: Future[Int] = Future{ Thread.sleep(10000) 2}

println(Await.result(f,12.seconds))//2

Page 16: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Blocking - Await

● Blocking: Await (Problem: Not enough time)

import scala.concurrent._import scala.concurrent.duration._import scala.concurrent.ExecutionContext.Implicits.global

val f: Future[Int] = Future{ Thread.sleep(10000) 2}

println(Await.result(f,5.seconds))

java.util.concurrent.TimeoutException: Futures timed out after [5 seconds]

Page 17: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Non-blocking - Callbacks

● Non-Blocking: callbacks

import scala.concurrent._import scala.concurrent.ExecutionContext.Implicits.global

val f: Future[Int] = Future{ Thread.sleep(10000) 2}

f.onComplete( n => println(n) )

//at some point, “Success(2)” will appear

Non-blocking

Page 18: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Callbacks

● Callbacks will be executed asynchronously when future is completed

● type Callback = Try[T] => Unit

● Try[T] ~ Either[Throwable,T]

○ Left(throwable) ~ Failure(throwable)

○ Right(t) ~ Success(t)

Page 19: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Callbacks

● onComplete

f.onComplete( (t: Try[Int]) => println(t) )//Success(2)

● onSuccess

f.onSuccess( n => println(n) )//2

● onFailure

f.onFailure( throwable => println(throwable.getMessage) )//it will never print an error (because it equals Success(2))

Page 20: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Operations

● map

def getFirstMillionOfPrimes(): Future[List[Int]] = ???

getFirstMillionOfPrimes().map( (list: List[Int]) => list.head)

res0: Future[Int]

Page 21: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Operations

● flatMap

def getFirstMillionOfPrimes(): Future[List[Int]] = ???

def concatenate(l: List[Int]): Future[String] = ???

getFirstMillionOfPrimes().flatMap( (list: List[Int]) => concatenate(list))

res0: Future[String]

Page 22: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Monad behavior

● Composition

○ Future is like a monad■ Point Function: Future.apply■ Bind Function: flatMap■ Some math properties and so...

○ Since Future has map,flatMap,filter methods; it can be composed easily in a for-comprehension

Page 23: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 24: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Composition

● Problem

var result: String = “”

val f1: Future[Unit] = Future{ result += “Hi ”}val f2: Future[Unit] = Future{ result += “ everyone”}

● result value? “Hi everyone”? “ everyoneHi”?

Page 25: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 26: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Composition

● for-comprehension is your friend

for { primes <- getFirstMillionPrimes() primesString <- concatenate(primes)} yield primesString

res0: Future[String]

Future[List[Int]]

Future[String]

Page 27: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Recovering from failure

● recover

val f: Future[Int] = Future{ 1 / 0 }.recover{ case e: ArithmeticException => 0}

Page 28: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Recovering from failure

● recoverWith

val f: Future[Int] = Future{ 1 / 0 }.recoverWith{ case e: ArithmeticException => Future(0)}

Page 29: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future: Recovering from failure

● fallbackTo

val f1: Future[Int] = Future{ 1 / 0 }

val f2: Future[Int] = Future(0)

val f = f1 fallbackTo f2

Page 30: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Promise: Overview

● Futures can be created by○ Future.apply○ Promises

● You can think about it like○ Future ~ Read future value○ Promise ~ Write future value

● Promises are single-assigned (just once. Immutable as futures)

Page 31: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Promise: Baggage & claim

Menuorder

MenuBeing

Cooked

Ticket

Menu ready

Page 32: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Promise: Baggage & claim

Begincompletion

Future[T]

p.successor

p.failure

Try[T]

Promise[T]

Page 33: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Promise: example

val r: T = produceSomething()

p success r

doSomethingElse()

startDoingSomething()

f onSuccess {

case r: T => handleResult()

}

val p = promise[T]

val f = p.future

Producer Consumer

Page 34: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Promise: completion

● complete

val p = promise[Int]p.complete(Try(2))

● completeWith

val p = promise[Int]p.completeWith(Future(2))

Page 35: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Future alternatives

● Scalaz futures

● Scala’s async library

Page 36: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Tones of slides and however...

Futures/Promises

Akka actors

Page 37: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 38: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: main concepts

● Actors, actors everywhere

● Asynchronous messages

● Event-driven processes

● Distributed systems

Page 39: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Actors

● Black box

● State without race condition

● Messages to update the state

Page 40: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Actors

class MyFirstActor extends Actor { override def receive = { case _ => println("Hello World!") }

}

Page 41: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Send a message

● Tell message

actor ! "Hi"

● Ask message

actor ? "Are you there"

Page 42: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Ask pattern

implicit val timeout = Timeout(5 seconds)

val f: Future[String] = (actorRef ? AreYouThere).mapTo[String]

Page 43: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: An example

Page 44: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Services userservice

contactservice

addressservice

System

GetUser(id)

GetContacts(name)

GetAddress(name)

Option[User]

List[Contact]

AddressUserInfo

Page 45: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Ask Pattern & For Comprehension

class UserServiceActor extends Actor {

val users: Map[String, User] = Map("1" -> User("John"), "2" -> User("Jack"))

override def receive = { case GetUser(userId: String) => sender ! users.get(userId) } }

Page 46: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka: Ask Pattern & For Comprehension

def getInfo(userId: String): Future[UserInfo] = for { Some(user) <- (usersActor ? GetUser(userId))

.mapTo[Option[User]] contacts <- (contactsActor.?(GetContacts(user.name))

(Timeout(5 seconds),context.self)).mapTo[List[Contact]]

address <- (addressesActor ? GetAddress(user.name)).mapTo[Address]

} yield UserInfo(user, contacts, address)

Page 47: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 48: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

scalera.es

@scalerablog

Page 49: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 50: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Primeros pasos con Akka:Olvídate de los threads

27 NOVEMBERTRACK D

18:00

Page 51: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Caminando de Java a Scala en menos de 2 horas

28 NOVEMBERTRACK B

9:30

Page 52: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Page 53: Codemotion 2015 - Akka voló sobre el nido del future

MADRID · NOV 27-28 · 2015

Scala Programming @ Madrid

Akka voló sobre el nido del FutureJavier SantosDavid Vallejo