Last active
February 16, 2023 03:33
-
-
Save shyan1/34f86ec49a01bd6b4630f9d2e4926126 to your computer and use it in GitHub Desktop.
Composable Futures with Akka 2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Youtube link: youtube.com/watch?v=VCattsfHR4o | |
| Threads | |
| - Independent, heap-sharing execution contexts | |
| - Scheduled by the Operating System | |
| - Creation is expensive in Java | |
| - Pools create additional complexity | |
| - Cache coherency issues | |
| Standard Thread Pools | |
| - Cached | |
| - Fixed | |
| - Scheduled | |
| - Single | |
| - Single scheduled | |
| - Fork/join (JDK7 and improved jsr166y) | |
| - Variants with/without daemon threads often required | |
| Concurrency Definitions | |
| - Concurrent tasks are stateful, often with complex interactions | |
| - Parallelizable tasks are stateless, do not interact, and are composable | |
| 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()` | |
| j.u.c Primitives | |
| - Callable, Runnable | |
| - Threads, thread pools and Executors | |
| - CompletionService, CountDownLatch, concurrent collections, CyclicBarrier, | |
| Phaser, Semaphone, TimeUnit | |
| - Primitive `Future<T>` | |
| j.u.c Is Too Hard To Use | |
| - Multithreaded programs tend to be buggy | |
| - 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. | |
| Concurrency Hazards | |
| - CPU registers | |
| - L1, L2 and L3 caches | |
| - L1 cache for each core | |
| - L2 cache shared by pairs of cores | |
| - L3 cache shared by all cores | |
| - Processors are different, so a program may run fine on one system but fail on another | |
| MESI Protocol | |
| - Each processor cache can be in one of four states | |
| - Modified | |
| - Exclusive | |
| - Shared | |
| - 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.) | |
| 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). | |
| Better Concurrency Options | |
| - Ordered by increasing complexity & overhead | |
| - j.u.c | |
| - Scala parallel collections | |
| - Akka futures (Java & Scala) | |
| - Akka/Scala dataflow | |
| - Akka actors (Java & Scala) | |
| - You can mix & match the above | |
| Scala Parallel Collections | |
| - Very easy to use | |
| - Not configurable | |
| - Block | |
| - Composable | |
| - Easy to reason with | |
| - Benefits from ongoing improvements to ForkJoinPool | |
| 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 asynchrnous activities | |
| - Good for consolidating multiple sources of data | |
| Akka Actors | |
| - Callable from Java & Scala | |
| - Over-hyped | |
| - 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 | |
| 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 | |
| What is a Future ? | |
| - Holder for a result that will become available at 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) | |
| 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 | |
| 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 | |
| Akka Future Operations | |
| - flatMap, map | |
| - flow | |
| - foreach, zip, firstCompletedOf, fold, reduce, sequence, traverse | |
| - andThen, fallbackTo, onComplete, onFailure, onSuccess, recover | |
| Composable Futures Rock | |
| - Twitter uses composable (Twitter) futures, no actors | |
| - KloutAPI uses Play Framework `AsyncResults`, fed by Akka futures, Load dropped in half | |
| 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 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment