Composable Futures with Akka 2.0


Published on

Writing concurrent programs that can run in multiple threads and on multiple cores is crucial but daunting. Futures provides a convenient abstraction for many problem domains. The online course "Intermediate Scala" includes an up-to-date discussion of futures and the parts of java.util.concurrent that underlie the Scala futures implementation. Unlike Java's futures, Scala futures supports composition, transformations and sophisticated callbacks.

The author is managing editor of, which offers self-paced online courses that teach Introductory and Intermediate Scala and Play Framework.

Published in: Technology, Business
  • Which slide are you referring to? In the talk I give, I cite sources, when appropriate. For example, I cite Martin Odersky, but he did not reference his sources. I am happy to give further references, if I know them. See
    Are you sure you want to  Yes  No
    Your message goes here
  • This slide was taken from Kunle Olukotun et al.-- though no mention given?
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Opteron and Intel i7 caches are quite different, for example
  • Scala futures?
  • Composable Futures with Akka 2.0

    1. 1. Composable Futures with Akka 2.0 by Mike Slinn #akkafuture at Googleplex April 18, 2012
    2. 2. Outline• Concurrency 101• Akka concurrency options• Foundation: java.util.concurrent• Definitions• Functional programming and concurrency• Performance tuning• 3 demos
    3. 3. Available
    4. 4. About Mike Slinn• Principal at Micronautics Research• Hands-on architect, mentor, trainer• Interim technical leader for companies in transition• Recognized in US Federal court as a software expert• Author of Composable Futures with Akka 2.0• Interested in artificial personality• Coordinator of BASE and Scala for Startups
    5. 5. Horizontal Scale – More Cores
    6. 6. Threads• Independent, heap-sharing execution contexts• Scheduled by the operating system• Creation is expensive in Java• Pools create additional complexity• Cache coherency issues
    7. 7. Multithreading and Callbacks
    8. 8. Standard Thread Pools• Cached• Fixed• Scheduled• Single• Single scheduled• Fork / join (JDK 7 and improved jsr166y)• Variants with/without daemon threads often required
    9. 9. Concurrency Definitions• Concurrent tasks are stateful, often with complex interactions• Parallelizable tasks are stateless, do not interact, and are composable
    10. 10. java.util.concurrent• Akka is built on top of java.util.concurrent (j.u.c.)• Futures are designed to be used with a Callable, which returns a result• Executors contain factories and utility methods for concurrent classes• ExecutorService.shutdown()
    11. 11. j.u.c. Primitives• Callable, Runnable• Threads, thread pools and Executors• CompletionService, CountDownLatch, concurrent collections, CyclicBarrier, Phaser, Semaphone, TimeUnit• Primitive Future<T>
    12. 12. j.u.c. Is Too Hard To Use• Multithreaded programs tend to be buggy o Non-determinism caused by concurrent threads accessing (shared) mutable state.• Actors and transactions manage state and are therefore not the first solution you should consider.• To get deterministic processing, avoid (shared) mutable state.
    13. 13. Concurrency Hazards• CPU registers• L1, L2 and L3 caches o L1 cache for each core o L2 cache shared by pairs of cores o L3 cache shared by all cores• Processors are different, so a program may run fine on one system but fail on another
    14. 14. Cache Line Ping-PongResult Array (Scala)var data = Array(threadCount)
    15. 15. Cache Line Ping-Pong• 8.5 ms vs. 830 ms (C# code)• Multicore efficiency: 10%
    16. 16. MESI Protocol• Each processor cache can be in one of four states: o Modified o Exclusive o Shared o Invalid• When one core writes to main memory, the entire cache block is marked invalid• Block sizes depend on processor (64 bytes, 128 bytes, etc.)
    17. 17. Cache Line Ping-Pong• Manifests even when external state is not shared o One or more cores repeatedly invalidate caches of the other cores, even while accessing isolated state. o The other cores must read data from main memory instead of their local cache o Slows program up to two orders of magnitude.
    18. 18. Cache Line Ping-Pong1.j.u.c. solution:@volatile var data = Array(threadCount)synchronized(data) { data(i) = whatever}2.Do not access external mutable state from a thread3. Use functional programming techniques
    19. 19. Large, Realtime Guidelines by Prismatic• Use functional programming to build fine- grained, flexible abstractions.• Compose these abstractions to express problem-specific logic.• Prefer lightweight, composable custom abstractions rather than monolithic frameworks (e.g., Hadoop).
    20. 20. Functional-Style Pipelines• *nix pipes (linear)• Scala parallel collections & Akka composable futures (parallel)
    21. 21. Better Concurrency Options• Ordered by increasing complexity & overhead o j.u.c. o Scala parallel collections o Akka futures* (Java & Scala) o Akka/Scala dataflow* o Akka actors (Java & Scala)• You can mix & match the above* Covered in my book: “Composable Futures with Akka 2.0” Covered in my April 23 InfoQ article.
    22. 22. Scala Parallel Collections• Very easy to use• Not configurable• Block• Composable• Easy to reason with• Benefits from ongoing improvements to ForkJoinPool o (Scala uses jsr166y)
    23. 23. Akka and j.u.c.
    24. 24. Akka Dispatchers and j.u.c.
    25. 25. Akka/Scala Dataflow*• Callable from Scala only• Has peculiar operators• Easy to reason with• Designed for shared mutable state• Dataflow blocks are composable• Good for coordination of asynchronous activities• Good for consolidating multiple sources of data
    26. 26. Akka Actors• Callable from Java & Scala• Over-hyped (remember EJB 2?)• Most complex option• Distributed concurrency: can scale beyond one motherboard• Not composable• Can be difficult or impossible to prove correct• This should be your last option to consider
    27. 27. Akka Futures• Callable from Java & Scala• More flexible than Scala parallel collections• Much less complex than Akka actors• Composable• Easy to reason with• Payloads (Callables) should not have side effects• Should not be used with shared mutable state
    28. 28. What is a Future?• Holder for a result that will become available at a later time.• Each future is backed by a thread.• If the computation fails, the future can also hold the resulting Throwable.• Write-once (immutable)• Akka and Twitter futures are composable and transformable (j.u.c. futures are not)
    29. 29. Akka & Twitter Futures• Manage concurrency• Higher-level than j.u.c. primitives• Immutable• Inexpensive• Can be preset to a value or exception when created.• Blocking and non-blocking operations supported
    30. 30. Composable Futures• Operations on a future or a collection of futures can be chained together without blocking• Transformations such as map and flatMap can be applied to a single future• Collections of futures can be manipulated
    31. 31. Akka Future Operations• flatMap, map• flow• foreach, zip, firstCompletedOf, fold, reduce, sequence, traverse• andThen, fallbackTo, onComplete, onFailure, onSuccess, recover
    32. 32. Composable Futures Rock• Twitter uses composable (Twitter) futures, no actors• KloutAPI uses Play Framework AsyncResults, fed by Akka futures. Load dropped in half
    33. 33. ExecutorBenchmark
    34. 34. Statistical Nature Large standard deviation; values are not tightly clustered around the median; results vary a lot each time a measurement is taken.Small standard deviation; values are tightly clustered around the median; results do not vary much each time a measurement is taken.
    35. 35. Standard Deviation• Measurements tend to lie within one standard deviations either side of the mean
    36. 36. Configure Thread Pools at Deployment• Number and type of processors and other hardware affects behavior• Interaction with other thread pools• Akka supports configuration files and configuration strings for setting up thread pools
    37. 37. Demo Time!• Simple futures• Try / catch / finally constructs• flatMap
    38. 38. flatMap Demo• Combination of and List.flatten()• Walks through a list and generates a second list by flattening each item in the first list• Will not evaluate the passed-in functor if the future failed• This demo implements the pseudo-code that Marius Eriksen of Twitter showed for flatMap last week at the Bay Area Scala Enthusiasts meetup
    39. 39. flatMap Demo1.Look up a token; return the user ID if successful, otherwise fail.2. Use the user ID to obtain a user information if step 1 did not fail.
    40. 40. Code Summaryval userF: Future[User] = Future(authenticate(token)) flatMap(id => getUser(id))userF onComplete { case Right(value: User) => println(value) case Left(exception) => println(exception.getMessage)}
    41. 41. Thank you! Mike Slinn