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

@apnyll...
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/no...
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 r...
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 == "...
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
...
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...
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[...
But, wait a minute, where is it executed?

•
•

Scala

• Implicit execution context required

• map(A => B)(implicit ctx)
...
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
•
?
•...
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...
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
...
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)
C...
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 mista...
How to make sync async

•

•

Futures

•

Important: using a separate bounded

•

scala.concurrent.blocking

ExecutionCont...
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 connecti...
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@mejs...
Upcoming SlideShare
Loading in …5
×

Async - react, don't wait - PingConf

2,856 views

Published on

Slides from my talk about Async with Play framework Scala and Java from the PingConf in Budapest january 2014

Published in: Technology
  • Be the first to comment

Async - react, don't wait - PingConf

  1. 1. Async React instead of waiting for better times Johan Andrén johan.andren@mejsla.se @apnylle
  2. 2. Who am I? Johan Andrén Java/JVM - Last 8 years Scala & Play - Last 2 years Home Consultant You are here now @apnylle
  3. 3. Most modern web frameworks Request t1 Thread pool t1 Response
  4. 4. What does that thread spend most of its time doing? Hint:
  5. 5. Wait Request your logic Request Blocked your logic Response resource Response
  6. 6. Why is this a problem? 20 db connections 200 threads 200 concurrent db-using reqs 1 req for non db url
  7. 7. Why is this a problem? (also) • Streaming data over http • many threads - overhead(s) • Cloud providers - thread cap/node
  8. 8. How would we like it to work? No logic executing: no thread taken resource
  9. 9. Don´t call us We´ll call you Our logic Our logic Async API Resource
  10. 10. 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
  11. 11. What do we need? • • Ways to do callbacks Framework support but doesn’t callbacks lead to...
  12. 12. ”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 }!
  13. 13. 25 }! 26 }); Not with better abstractions! • Futures / Promises • Iteratees • Actors
  14. 14. ! SH K A R A H RK! S Intermission SHARK!
  15. 15. 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”
  16. 16. complete(kitten) failure(Reason) Future[Kitten] Promise[Kitten] Side effect!!! onComplete(play) onFailure(cry)
  17. 17. Transforming the future Future[B] Future[A] a map(f: A => B) f(a) b
  18. 18. If the future isn’t that bright Future[A] Future[B] Map
  19. 19. Example - the play web client : Future[SimpleResult]
  20. 20. Example - the play web client
  21. 21. Chaining futures Future[A] WS Response => model Object map(A => B) Future[B] model Object => HTML map(B => C) Future[C]
  22. 22. Even more flexibility flatMap(A => Future[B]) Future[B] Future[A] List[Future[A]] Future[List[A]] Future.sequence
  23. 23. Even more even more flexibility List[Future[A]] Future[A] Future.firstCompletedOf List[Future[A]] Future.fold Future[B]
  24. 24. But, wait a minute, where is it executed? • • Scala • Implicit execution context required • map(A => B)(implicit ctx) Java • map(A => B, CTX) • Default
  25. 25. ExecutionContext Runnable:s Threadpool T1 T 2 T n
  26. 26. So, when should I use futures? • When talking to other services 
 (ws, db, etc) • Simple one off background stuff • ? • For parallell work
  27. 27. Inbox State Actors Behaviour
  28. 28. Example - actors and the ask pattern
  29. 29. Example - actors and the ask pattern
  30. 30. Example - actors and the ask pattern
  31. 31. Request 1 Request 2 Response 1 Thread 1 Response 2 Thread 2 Threads blocked! Request 3 Thread 3 Response 3 Shared Mutable Resource
  32. 32. Response 1 Request 1 Request 2 Response 2 Request 3 Response 3 Actor with state
  33. 33. 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 • ? •
  34. 34. Small, simple and witty illustration of Iteratees (best case: including cats) Iteratees
  35. 35. Traditional imperative Java IO Thread blocked!
  36. 36. How would we want it to work? • • • react on each chunk build something out of those chunks bail out early
  37. 37. Let’s model that: Input El(element) EOF Empty
  38. 38. Let’s model that: Step What to do with next input put =>Step) Cont(In Done(result) Error(why)
  39. 39. 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
  40. 40. Let’s model that: Enumerator[E] E: The type of the chunks Iteratee[E, R]
  41. 41. Even moar: Enumeratee[A, B] Enumerator[A] Iteratee[B, R]
  42. 42. Example
  43. 43. Example
  44. 44. Example
  45. 45. So, when should I use Iteratees? • When you need to stream data • You probably already do! • ? (BodyParsers)
  46. 46. Async: What to look out for • • • • • IO Enumerator.from{File|Stream} Really heavy/long computations Blocking by mistake JDBC
  47. 47. How to make sync async • • Futures • Important: using a separate bounded • scala.concurrent.blocking ExecutionContext Actors
  48. 48. Async: Drawbacks • • • MMMM - (Monad-Mixing Makes Mess) Shorter stacks - stacktraces not that helpful :( ThreadLocal
  49. 49. 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
  50. 50. Final words Play makes async easy (and fun) both with Java and Scala! Also: Know your abstractions!
  51. 51. Qs? K Thx Bye! github.com/johanandren/ping-conf-scala github.com/johanandren/ping-conf-java Johan Andrén johan.andren@mejsla.se @apnylle

×