Asynchronous Scala
April 2015, Javier Santos
Promising futures...
Javier Santos Paniego
Scala Developer
jsantos@stratio.com
CONTACT
INTRODUCTION
• Functional World
• Runnable/Callable
• Threads
1 2 3FUTURES
• Completion
• ExecutionContext
• Callbacks
• Future monad
• Composition
• Recovery
PROMISES
• Baggage & Claim
• Completion
INDEX
Introduction
Introduction
Asynchronous Scala: Promising futures
● Purely functional: whole world could be implemented in a single
functional line
● Functional features
○ Robust
○ Debuggable
○ Predictable
○ Pluggable
Introduction
A functional world
Asynchronous Scala: Promising futures
● 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),actions) =>
action.apply(context) match {
case (context,event) => (context, events :+ event)
}
}
}
Introduction
A functional world
Asynchronous Scala: Promising futures
● 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.
Introduction
A functional world
Asynchronous Scala: Promising futures
● java.lang.Runnable
trait Runnable {
def run(): Unit
}
● java.util.concurrent.Callable
trait Callable[V] {
def call(): V
}
Introduction
Runnable & Callable
Asynchronous Scala: Promising futures
● Scala’s concurrency model is built on Java’s
● java.lang.Thread
val myThread = new Thread(new Runnable {
def run(){
println(“hi”)
}
}
myThread.start()
Introduction
Threads
Asynchronous Scala: Promising futures
● Thread improvements
○ ExecutorService (obtained from static Executors) allows using
thread policies (like threading pools)
val pool: ExecutorService = Executors.newFixedThreadPool(poolSize)
pool.execute(new Runnable{
def run(){
println(“I’m handling a request”)
}
})
○ Anyway, Threads abstraction level is too low
Introduction
Thread policies
Futures
Futures
Asynchronous Scala: Promising futures
● 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 value
It will have two possible values:
○ Success(t: T)
○ Failure(t: Throwable)
Futures
Overview
Asynchronous Scala: Promising futures
● Successfully completion 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(100000)'…
}
res0: Future[List[Int]]
Futures
Success on completion
Asynchronous Scala: Promising futures
● Failure completion example
import scala.concurrent._
import ExecutionContext.Implicits.global
val thisWillFail: Future[Int] = Future(2 / 0)
res0: Future[Int]
Futures
Failure on completion
Asynchronous Scala: Promising futures
● 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.
Futures
ExecutionContext
Asynchronous Scala: Promising futures
● Expecting results.
○ Blocker way (discouraged but sometimes mandatory).
○ Non-blocker way: using callbacks
Futures
Expecting results
Asynchronous Scala: Promising futures
● 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
Futures
Blocking: Await
Asynchronous Scala: Promising futures
● 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]
Futures
Blocking: Await problem
Asynchronous Scala: Promising futures
● Non-Blocking: callbacks
import scala.concurrent._
import scala.concurrent.duration._
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
Futures
Non-blocking: Callbacks
Non-blocking
Asynchronous Scala: Promising futures
● Callbacks will be executed asynchronously when future is
completed
● Try[T] => U
● Try[T] ~ Either[Throwable,T]
○ Left(throwable) ~ Failure(throwable)
○ Right(t) ~ Success(t)
Futures
Callbacks
Asynchronous Scala: Promising futures
● onComplete
f.onComplete( (t: Try[Int]) => println(n) )
//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))
Futures
Callbacks
Asynchronous Scala: Promising futures
● Composition
○ Future is a monad
■ Type Constructor: T => Future[T]
■ Unit Function: Future.apply
■ Bind Function: flatMap
○ Since Future has map,flatMap,filter methods; it can be composed
easily in a for-comprehension
Futures
Monad behavior
Asynchronous Scala: Promising futures
Futures
Monad behavior
Asynchronous Scala: Promising futures
● map
def getFirstMillionOfPrimes(): Future[List[Int]] = ???
getFirstMillionOfPrimes().map(
(list: List[Int]) => list.head)
res0: Future[Int]
Futures
Monad behavior
Asynchronous Scala: Promising futures
● flatMap
def getFirstMillionOfPrimes(): Future[List[Int]] = ???
def concatenate(l: List[Int]): Future[String] = ???
getFirstMillionOfPrimes().flatMap((list: List[Int]) => concatenate(list))
res0: Future[String]
Futures
Monad behavior
Asynchronous Scala: Promising futures
● Problem
var result: String = “”
val f1: Future[Unit] = Future{result += “Hi ”}
val f2: Future[Unit] = Future{result += “ everyone”}
● result value?
Futures
Composition
Asynchronous Scala: Promising futures
● for-comprehension is your friend
for {
primes <- getFirstMillionPrimes()
primesString <- concatenate(primes)
} yield primes
res0: Future[String]
Futures
Composition
Future[List[Int]]
Future[String]
Asynchronous Scala: Promising futures
● recover
val f: Future[Int] = Future{
1 / 0
}.recover{
case e: ArithmeticException => 0
}
Futures
Recovering from failure
Asynchronous Scala: Promising futures
● recoverWith
val f: Future[Int] = Future{
1 / 0
}.recoverWith{
case e: ArithmeticException => Future(0)
}
Futures
Recovering from failure
Asynchronous Scala: Promising futures
● fallbackTo
val f1: Future[Int] = Future{
1 / 0
}
val f2: Future[Int] = Future(0)
val f = f1 fallbackTo f2
Futures
Recovering from failure
Promises
Promises
Asynchronous Scala: Promising futures
● 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)
Promises
Overview
Asynchronous Scala: Promising futures
Promises
Baggage & claim pattern
Menu
order
Menu
Being
Cooked
Ticket
Menu
Ready
Asynchronous Scala: Promising futures
Promises
Baggage & claim pattern
Promise[T]
Begin
completion
Future[T]
p.success
or
p.failure
Try[T]
Asynchronous Scala: Promising futures
Promises
Example
val producer = future {
val r: T = produceSomething()
p success r
continueDoingSomethingUnrelated()
}
val consumer = future {
startDoingSomething()
f onSuccess {
case r: T => handleResult()
}
}
val p = promise[T]
val f = p.future
Asynchronous Scala: Promising futures
● complete
val p: Promise[Int]
p.complete(Try(2))
● completeWith
val p: Promise[Int]
p.completeWith(Future(2))
Promises
Overview
Asynchronous Scala: Promising futures
Finished...
...for today
Futures/Promises
Akka actors
Still interested?
● Scala school (Twitter)
● Reactive Design Patterns, Roland
Kuhn and Jamie Allen
● Scala-lang docs: Futures and
promises
● Akka doc - Futures
Introduction to Asynchronous scala

Introduction to Asynchronous scala

  • 1.
    Asynchronous Scala April 2015,Javier Santos Promising futures...
  • 2.
    Javier Santos Paniego ScalaDeveloper jsantos@stratio.com CONTACT INTRODUCTION • Functional World • Runnable/Callable • Threads 1 2 3FUTURES • Completion • ExecutionContext • Callbacks • Future monad • Composition • Recovery PROMISES • Baggage & Claim • Completion INDEX
  • 3.
  • 4.
    Asynchronous Scala: Promisingfutures ● Purely functional: whole world could be implemented in a single functional line ● Functional features ○ Robust ○ Debuggable ○ Predictable ○ Pluggable Introduction A functional world
  • 5.
    Asynchronous Scala: Promisingfutures ● 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),actions) => action.apply(context) match { case (context,event) => (context, events :+ event) } } } Introduction A functional world
  • 6.
    Asynchronous Scala: Promisingfutures ● 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. Introduction A functional world
  • 7.
    Asynchronous Scala: Promisingfutures ● java.lang.Runnable trait Runnable { def run(): Unit } ● java.util.concurrent.Callable trait Callable[V] { def call(): V } Introduction Runnable & Callable
  • 8.
    Asynchronous Scala: Promisingfutures ● Scala’s concurrency model is built on Java’s ● java.lang.Thread val myThread = new Thread(new Runnable { def run(){ println(“hi”) } } myThread.start() Introduction Threads
  • 9.
    Asynchronous Scala: Promisingfutures ● Thread improvements ○ ExecutorService (obtained from static Executors) allows using thread policies (like threading pools) val pool: ExecutorService = Executors.newFixedThreadPool(poolSize) pool.execute(new Runnable{ def run(){ println(“I’m handling a request”) } }) ○ Anyway, Threads abstraction level is too low Introduction Thread policies
  • 10.
  • 11.
    Asynchronous Scala: Promisingfutures ● 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 value It will have two possible values: ○ Success(t: T) ○ Failure(t: Throwable) Futures Overview
  • 12.
    Asynchronous Scala: Promisingfutures ● Successfully completion 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(100000)'… } res0: Future[List[Int]] Futures Success on completion
  • 13.
    Asynchronous Scala: Promisingfutures ● Failure completion example import scala.concurrent._ import ExecutionContext.Implicits.global val thisWillFail: Future[Int] = Future(2 / 0) res0: Future[Int] Futures Failure on completion
  • 14.
    Asynchronous Scala: Promisingfutures ● 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. Futures ExecutionContext
  • 15.
    Asynchronous Scala: Promisingfutures ● Expecting results. ○ Blocker way (discouraged but sometimes mandatory). ○ Non-blocker way: using callbacks Futures Expecting results
  • 16.
    Asynchronous Scala: Promisingfutures ● 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 Futures Blocking: Await
  • 17.
    Asynchronous Scala: Promisingfutures ● 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] Futures Blocking: Await problem
  • 18.
    Asynchronous Scala: Promisingfutures ● Non-Blocking: callbacks import scala.concurrent._ import scala.concurrent.duration._ 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 Futures Non-blocking: Callbacks Non-blocking
  • 19.
    Asynchronous Scala: Promisingfutures ● Callbacks will be executed asynchronously when future is completed ● Try[T] => U ● Try[T] ~ Either[Throwable,T] ○ Left(throwable) ~ Failure(throwable) ○ Right(t) ~ Success(t) Futures Callbacks
  • 20.
    Asynchronous Scala: Promisingfutures ● onComplete f.onComplete( (t: Try[Int]) => println(n) ) //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)) Futures Callbacks
  • 21.
    Asynchronous Scala: Promisingfutures ● Composition ○ Future is a monad ■ Type Constructor: T => Future[T] ■ Unit Function: Future.apply ■ Bind Function: flatMap ○ Since Future has map,flatMap,filter methods; it can be composed easily in a for-comprehension Futures Monad behavior
  • 22.
    Asynchronous Scala: Promisingfutures Futures Monad behavior
  • 23.
    Asynchronous Scala: Promisingfutures ● map def getFirstMillionOfPrimes(): Future[List[Int]] = ??? getFirstMillionOfPrimes().map( (list: List[Int]) => list.head) res0: Future[Int] Futures Monad behavior
  • 24.
    Asynchronous Scala: Promisingfutures ● flatMap def getFirstMillionOfPrimes(): Future[List[Int]] = ??? def concatenate(l: List[Int]): Future[String] = ??? getFirstMillionOfPrimes().flatMap((list: List[Int]) => concatenate(list)) res0: Future[String] Futures Monad behavior
  • 25.
    Asynchronous Scala: Promisingfutures ● Problem var result: String = “” val f1: Future[Unit] = Future{result += “Hi ”} val f2: Future[Unit] = Future{result += “ everyone”} ● result value? Futures Composition
  • 26.
    Asynchronous Scala: Promisingfutures ● for-comprehension is your friend for { primes <- getFirstMillionPrimes() primesString <- concatenate(primes) } yield primes res0: Future[String] Futures Composition Future[List[Int]] Future[String]
  • 27.
    Asynchronous Scala: Promisingfutures ● recover val f: Future[Int] = Future{ 1 / 0 }.recover{ case e: ArithmeticException => 0 } Futures Recovering from failure
  • 28.
    Asynchronous Scala: Promisingfutures ● recoverWith val f: Future[Int] = Future{ 1 / 0 }.recoverWith{ case e: ArithmeticException => Future(0) } Futures Recovering from failure
  • 29.
    Asynchronous Scala: Promisingfutures ● fallbackTo val f1: Future[Int] = Future{ 1 / 0 } val f2: Future[Int] = Future(0) val f = f1 fallbackTo f2 Futures Recovering from failure
  • 30.
  • 31.
    Asynchronous Scala: Promisingfutures ● 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) Promises Overview
  • 32.
    Asynchronous Scala: Promisingfutures Promises Baggage & claim pattern Menu order Menu Being Cooked Ticket Menu Ready
  • 33.
    Asynchronous Scala: Promisingfutures Promises Baggage & claim pattern Promise[T] Begin completion Future[T] p.success or p.failure Try[T]
  • 34.
    Asynchronous Scala: Promisingfutures Promises Example val producer = future { val r: T = produceSomething() p success r continueDoingSomethingUnrelated() } val consumer = future { startDoingSomething() f onSuccess { case r: T => handleResult() } } val p = promise[T] val f = p.future
  • 35.
    Asynchronous Scala: Promisingfutures ● complete val p: Promise[Int] p.complete(Try(2)) ● completeWith val p: Promise[Int] p.completeWith(Future(2)) Promises Overview
  • 36.
    Asynchronous Scala: Promisingfutures Finished... ...for today Futures/Promises Akka actors
  • 37.
    Still interested? ● Scalaschool (Twitter) ● Reactive Design Patterns, Roland Kuhn and Jamie Allen ● Scala-lang docs: Futures and promises ● Akka doc - Futures