Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Don't Block - How to Mess Up Akka and Spray


Published on

Presented at Feb 2014 Iowa Scala Enthusiasts meetup:

Git repo contains runnable code samples not in slides:

Actors and Futures make writing concurrent, asynchronous, non-blocking, reactive applications much simpler than dealing with threads, locks and synchronization directly. However, it’s also really easy to inadvertently block in the wrong place and bring your entire system to a grinding halt. We’ll demonstrate some of the common, simple ways to destroy Akka and Spray applications, examine the internals of these libraries to explore what’s happening, and discuss some best practices they provide for avoiding these problems.

Published in: Technology

Don't Block - How to Mess Up Akka and Spray

  1. 1. Don't Block How to Mess Up Akka and Spray Zach Cox - @zcox - iascala - Feb 2014
  2. 2. Horse ebooks @Horse_ebooks Don t block 1:52 PM - 4 Aug 2013 467 RETWEETS 320 FAVORITES Follow
  3. 3. Purpose Scala provides great concurrency tools Very easy to mess up Demonstrate how blocking can prevent processing Provide solutions
  4. 4. Things We Will Block Threads (Java) Futures (Scala) Actors (Akka) Spray
  5. 5. Spoiler All about blocking threads
  6. 6. What is Blocking? Code that takes a long time to run Network I/O HTTP requests Database access File I/O Really heavy computation Nothing after the blocking function can run on this thread until it is done
  7. 7. Java: R n a l , E e u o unbe xctr tatRnal { ri unbe dfrn) Ui e u(: nt } tatEeuo { ri xctr dfeeuecmad Rnal) Ui e xct(omn: unbe: nt }
  8. 8. TraPoEeuo hedolxctr casTraPoEeuo etnsEeuo { ls hedolxctr xed xctr vlpo:StTra]=Stepy a ol e[hed vltss BoknQeeRnal]=?? a ak: lciguu[unbe ? dfeeuecmad Rnal) Ui ={ e xct(omn: unbe: nt /rncmado nwtra,o qeei,o rjc i,dpnigo stig.. /u omn n e hed r uu t r eet t eedn n etns. } }
  9. 9. How to block T r a P o E e u o hedolxctr Execute tasks that block in run() method All threads in pool get blocked Tasks are queued before execution (until queue is full) How it is supposed to work... Need to be aware of the blocking though
  10. 10. FrJiPo okonol E e u o S r i eimplementation xctrevc saacnurn.okon cl.ocretfrji j v . t l c n u r n (Java7) aaui.ocret Sub-dividing tasks, work queue, worker thread pool, work stealing, ...
  11. 11. How to block F r J i P o okonol Same as T r a P o E e u o hedolxctr
  12. 12. Solutions for Blocked E e u o xctr vleeuo =EeuosnwieTraPo(oehed) a xctr xctr.eFxdhedolmrTras vleeuo1=EeuosnwieTraPo(olSz) a xctr xctr.eFxdhedolpo1ie vleeuo2=EeuosnwieTraPo(olSz) a xctr xctr.eFxdhedolpo2ie
  13. 13. Java: C l a l , F t r , albe uue EeuoSrie xctrevc tatClal[]{ ri albeV dfcl(:V e al) } tatFtr[]{ ri uueV dfiDn(:Boen e soe) ola dfgt) V e e(: } tatEeuoSrieetnsEeuo { ri xctrevc xed xctr dfsbi(ak Rnal) Ftr[] e umtts: unbe: uue_ dfsbi[]ts:Clal[]:Ftr[] e umtT(ak albeT) uueT }
  14. 14. Ftr[] uueT Monad that eventually contains either: A value of type T(success) A T r w b e(failure) hoal F t r [ ]is the read-side; P o i e T is the write-side uueT rms[] Value is computed and placed into promise/future on some other thread (usually) /TD cmeln eapeo Ftr.. /OO oplig xml f uue.
  15. 15. Eeuinotx xctoCnet Runs code that asynchronously completes futures Scala version of E e u o /E e u o S r i e xctr xctrevc Implementations usually wrap one E e u o => E e u i n o t x xctr xctoCnet E e u o S r i e=> E e u i n o t x xctrevc xctoCnet F t r . p l runs body function using E e u i n o t x uueapy xctoCnet Wraps the body function in a R n a l unbe Executes that R n a l on an E e u i n o t x unbe xctoCnet That R n a l completes a P o i e unbe rms Eeuinotx.lbl xctoCnetgoa Tries to use F r J i P o okonol Falls back to T r a P o E e u o hedolxctr
  16. 16. How to block F t r /E e u i n o t x uue xctoCnet E e u i n o t x just wraps an E e u o /E e u o S r i e xctoCnet xctr xctrevc E e u i n o t x . l b lusually wraps either a xctoCnetgoa F r J i P o or a T r a P o E e u o okonol hedolxctr We already know how to block those tldr function passed to F t r . p l blocks the underlying thread, uueapy exhaust the pool
  17. 17. Solutions for blocked F t r /E e u i n o t x uue xctoCnet jv .. aa . -saacnurn.otx.iTras8 Dcl.ocretcnetmnhed= -saacnurn.otx.uTras1 Dcl.ocretcnetnmhed=6 -saacnurn.otx.aTras2 Dcl.ocretcnetmxhed=4 .. . ipii vlc=Eeuinotx.rmxctrEeuosnwieTraPo(2) mlct a xctoCnetfoEeuo(xctr.eFxdhedol13) ipii vldfutotx =Eeuinotx.lbl mlct a ealCnet xctoCnetgoa vldtbsCnet=Eeuinotx.rmxctrnl) a aaaeotx xctoCnetfoEeuo(ul Ftr(dfutpoesn" uue"eal rcsig) Ftr(dtbs oeain"(aaaeotx) uue"aaae prtos)dtbsCnet
  18. 18. Actors and Dispatchers atr!mg co s m gplaced in actor''s M i b xqueue s alo M i b xis a R n a l alo unbe M i b xexecuted on dispatcher''s E e u o S r i e alo xctrevc By default, all actors use the same default dispatcher
  19. 19. How to Block Actors Remember how to block E e u o ? Do that. xctr Block in A t r r c i e co.eev Enough blocked actors will exhaust the dispatcher''s thread pool
  20. 20. Solutions for Blocked Actors bokn2dsace { lcig-ipthr tp =Dsace ye ipthr eeuo ="okji-xctr xctr fr-oneeuo" } vlbokn =sse.coO(rp[lcigco] a lcig ytmatrfPosBoknAtr .ihotrFoCni() wtRue(rmofg) .ihipthr"lcig-ipthr) "lcig" wtDsace(bokn2dsace", bokn2) m-ipthr{ ydsace tp =Dsace ye ipthr eeuo ="okji-xctr xctr fr-oneeuo" fr-oneeuo { okji-xctr prleimfco =1. aalls-atr 00 prleimmx=10 aalls-a 0 } }
  21. 21. Fun Fact M s a e i p t h ris an E e u i n o t x esgDsace xctoCnet vljbCnet=sse.ipthr.okp"dcdsace" a dcotx ytmdsaceslou(jb-ipthr) Ftr(sTeaaae(dcotx) uueuehDtbs)jbCnet
  22. 22. Spray spray-io/akka-io: Java NIO + Actors spray-can: HTTP server & client built on spray-io spray-routing: HTTP request/response DSL
  23. 23. How to Block Spray Built on actors We know how to block those S m l R u i g p uses a single actor to route all requests (!!!) ipeotnAp That actor synchronously calls runRoute - easily blocked! That actor uses default Akka dispatcher - easily blocked! Example code
  24. 24. Solutions for Blocking Spray Do not call blocking functions directly in routes Instead detach to F t r or A t r uue co Spray can complete a response using a F t r uue Use separate dispatchers Give Spray its own dispatcher(s) Give your blocking code its own dispatcher(s)
  25. 25. Java NIO and spray-client Blocking I/O: One thread per socket Non-blocking I/O: One thread, many sockets No network I/O (web service client, database, etc) libraries use it! Except spray-client... Start writing Scala web service clients using spray-can! Other protocols (TCP, SMTP, XMPP, various DBs, etc) can use akka-io
  26. 26. Banno is Hiring Scala Developers!