Async React instead of waiting for better times Johan Andrén johan.andren@mejsla.se @apnylle
Who am I? Johan Andrén Java/JVM - Last 8 years Scala & Play - Last 2 years Home Consultant You are here now @apnylle
Most modern web frameworks Request t1 Thread pool t1 Response
What does that thread spend most of its time doing? Hint:
Wait Request your logic Request Blocked your logic Response resource Response
Why is this a problem? 20 db connections 200 threads 200 concurrent db-using reqs 1 req for non db url
Why is this a problem? (also) • Streaming data over http • many threads - overhead(s) • Cloud providers - thread cap/node
How would we like it to work? No logic executing: no thread taken resource
Don´t call us We´ll call you Our logic Our logic Async API Resource
Q We can’t really do more cpu-bound work than the number of cores simultaneously So If no thread ever blocks we don’t really need: more threads than cores
What do we need? • • Ways to do callbacks Framework support but doesn’t callbacks lead to...
”Callback Hell”? 1 GMaps.geocode({! 2 address: fromAddress,! 3 callback: function( results, status ) {! 4 if ( status == "OK" ) {! 5 fromLatLng = results[0].geometry.location;! 6 GMaps.geocode({! 7 address: toAddress,! 8 callback: function( results, status ) {! 9 if ( status == "OK" ) {! 10 toLatLng = results[0].geometry.location;! 11 map.getRoutes({! 12 origin: [ fromLatLng.lat(), fromLatLng.lng() ],! 13 destination: [ toLatLng.lat(), toLatLng.lng() ],! 14 travelMode: "driving",! 15 unitSystem: "imperial",! 16 callback: function( e ){! 17 console.log("ANNNND FINALLY here's the directions..." );! 18 // do something with e! 19 }! 20 });! 21 }! 22 }! 23 });! 24 }! 25 }!
25 }! 26 }); Not with better abstractions! • Futures / Promises • Iteratees • Actors
! SH K A R A H RK! S Intermission SHARK!
Futures ”I promise that I will give you a Kitten, when you are old enough to take care of it” ”When I (in the future) Get a kitten I will play with it all day”
complete(kitten) failure(Reason) Future[Kitten] Promise[Kitten] Side effect!!! onComplete(play) onFailure(cry)
Transforming the future Future[B] Future[A] a map(f: A => B) f(a) b
If the future isn’t that bright Future[A] Future[B] Map
Example - the play web client : Future[SimpleResult]
Example - the play web client
Chaining futures Future[A] WS Response => model Object map(A => B) Future[B] model Object => HTML map(B => C) Future[C]
Even more flexibility flatMap(A => Future[B]) Future[B] Future[A] List[Future[A]] Future[List[A]] Future.sequence
Even more even more flexibility List[Future[A]] Future[A] Future.firstCompletedOf List[Future[A]] Future.fold Future[B]
But, wait a minute, where is it executed? • • Scala • Implicit execution context required • map(A => B)(implicit ctx) Java • map(A => B, CTX) • Default
ExecutionContext Runnable:s Threadpool T1 T 2 T n
So, when should I use futures? • When talking to other services 
 (ws, db, etc) • Simple one off background stuff • ? • For parallell work
Inbox State Actors Behaviour
Example - actors and the ask pattern
Example - actors and the ask pattern
Example - actors and the ask pattern
Request 1 Request 2 Response 1 Thread 1 Response 2 Thread 2 Threads blocked! Request 3 Thread 3 Response 3 Shared Mutable Resource
Response 1 Request 1 Request 2 Response 2 Request 3 Response 3 Actor with state
So, when should I use actors? • When you need state Streaming data into or out of play • As a base for event driven apps • Background work • ? •
Small, simple and witty illustration of Iteratees (best case: including cats) Iteratees
Traditional imperative Java IO Thread blocked!
How would we want it to work? • • • react on each chunk build something out of those chunks bail out early
Let’s model that: Input El(element) EOF Empty
Let’s model that: Step What to do with next input put =>Step) Cont(In Done(result) Error(why)
Let’s model that: EL(”kittenA”) EL(”kittenB”) EOF Enumerator (Starting state) ut =>Step) Cont(Inp Cont(Input =>Step) Cont(Input =>Step) Done(List(”kittenA”,”kittenB”)) Iteratee
Let’s model that: Enumerator[E] E: The type of the chunks Iteratee[E, R]
Even moar: Enumeratee[A, B] Enumerator[A] Iteratee[B, R]
Example
Example
Example
So, when should I use Iteratees? • When you need to stream data • You probably already do! • ? (BodyParsers)
Async: What to look out for • • • • • IO Enumerator.from{File|Stream} Really heavy/long computations Blocking by mistake JDBC
How to make sync async • • Futures • Important: using a separate bounded • scala.concurrent.blocking ExecutionContext Actors
Async: Drawbacks • • • MMMM - (Monad-Mixing Makes Mess) Shorter stacks - stacktraces not that helpful :( ThreadLocal
Is there a case where async shouldn’t be used? Entirely cpu bound apps Possibly: Few (and predictable) concurrent connections and a need of as good response times as possible
Final words Play makes async easy (and fun) both with Java and Scala! Also: Know your abstractions!
Qs? K Thx Bye! github.com/johanandren/ping-conf-scala github.com/johanandren/ping-conf-java Johan Andrén johan.andren@mejsla.se @apnylle

Async - react, don't wait - PingConf