3. “The free lunch is over” / TANSTAAFL
Herb Sutter 2005 http://www.gotw.ca/publications/concurrency-ddj.htm
Number
of transistors
Clock Speed
4. Can‟t I just..
Parallelize
that Sh*t™?
Put that in a box!
Something like this?
Parallel
Version
9
Hey Oracle don‟t sue me, of course it‟s fake
5. Nope. Parallelize that Sh*t™
Not every algorithm can be parallelized
Dynamic coordination (concurrent)
Amdahl‟s Law
Sequential fraction determines max speedup
6. Threads?
Shared (mutable) state + locks
Require synchronization
Diminishing returns**
Which primitives to use?
Difficult to predict & maintain
Deadlock
Livelock
Thread starvation
Race condition
*Using threads directly is meant here
**Performance improvement degrades with more threads than cores.
7. “Life is too short for
Blocking code”*
*Mario Fusco just the other day on twitter
8. Why Async? Less latency.
Service
Service A
Service B
Service C
4 sec
6 sec
3 sec
Sync takes 13 seconds
Async takes max 6 seconds
Asynchronous „first completed response‟ is easy to do
9. 1. The world is concurrent
2. Things in the world don't share data
3. Things communicate with messages
4. Things fail
Joe Armstrong (creator of Erlang)
10. We need better tools to build..
Reactive*
Applications
* The latest need-to-know buzz word!
12. Scale Up and Out
Concurrent
Distributed
Many Nodes
Many ThreadsAkkaA uniform model for both up
and out, embraces
concurrency and failure
Maximize the use of cores
_and_ nodes.
Concurrent(moreCores)
Distributed (more Nodes)
14. Scale Up
Processes (even less**)
Actors (2.7 million / 1GB)
Threads (4096 / 1GB)
Actors are small*
* Disclaimer: text is not shown to scale, actors are way smaller..
** Especially JVM processes
20. Actor Instance
Crashed Actor
Instance
Mailbox
An Actor Instance crashes instead of handling
Exceptions. A Supervisor decides it‟s fate.
ActorRef
Restart / Resume / Stop / Escalate
New Actor
Instance
35. Inside our Main class…
val system = new ActorSystem(“goticks”)
Create
The system
ActorSystem(“goticks”)
36. Inside Main…
val system = new ActorSystem(“goticks”)
val api = system.actorOf(
Props[RestInterface],
“httpInterface”)
…
CREATE
RestInterface
ActorSystem(“goticks”)
Top Level Actor
ActorSystem(“goticks”)
REST Interface
37. Inside Main…
val system = new ActorSystem(“goticks”)
val api = system.actorOf(
Props[RestInterface],
“httpInterface”)
…
CREATE
RestInterface
ActorSystem(“goticks”)
Factory/Creator/ Immutable Configuration object
ActorSystem(“goticks”)
REST Interface
38. Inside Main…
val system = new ActorSystem(“goticks”)
val api = system.actorOf(
Props[RestInterface],
“httpInterface”)
…
CREATE
RestInterface
ActorSystem(“goticks”)
ActorRef to the Actor
ActorSystem(“goticks”)
REST Interface
44. Receiving messages
class BoxOffice extends Actor {
def receive = {
case TicketRequest(name) =>
…
case GetEvents =>
…
case event: Event =>
…
}
}
Pattern Matching
On Messages
45. Receiving messages
class TicketSeller extends Actor {
def receive = soldOut
def soldOut:Receive = {
case Tickets(newTickets) =>
.. //store new tickets
become(selling)
}
def selling:Receive = {
case BuyTicket(name) =>
…
}
}
Partial Function
3. BECOME:
You can change th
behavior at
every msg
TODOMake specific to Rabo -> Scala Java comparison.Show basic powerful features of Scala anyone would love. (REPL, case classes, pattern matching, collectionsVery simple example of Futures. Very simple example of Actor. Very simple example of Agent?
The free lunch is over. (Actually it has been over for a while now!)This graph is from an article by Herb Sutter of C++ fame.While the number of transistors per chip still increases, the clock speed has leveled out over the last coupld of years.Chip manufacturers focus on multi core abilities instead of higher clock speeds.So new chips will not immediately increase the speed of sequential programs.This means that concurrent programs are necessary to make full use of multi-core CPU’s
Can’t I just get these really smart compiler and runtime guys to do parallelization behind the scenes?Gimme that shiny box!Released in 2018? I kid.
Some part of your application is going to be sequential, which limits the improvement that can be achieved by parallel execution.Algorithms that require very low sequential execution can benefit the most from parallel execution.Example: Map Reduce style (batch) processing
ThreadsAn standalone execution path within a process - Has its own timeline- Call Stack- Shares Address space (Heap) with other Threads within the same process Performance improvement degrades with more threads than cores.Knowing up front which locks need to be locked Breaks encapsulationAll locks need to be taken before modification - in the correct orderAll locks must be unlocked Thread are expensive and their lifecycle management is error prone Traditional problem: Dining Philosophers
ThreadsAn standalone execution path within a process - Has its own timeline- Call Stack- Shares Address space (Heap) with other Threads within the same process Performance improvement degrades with more threads than cores.Knowing up front which locks need to be locked Breaks encapsulationAll locks need to be taken before modification - in the correct orderAll locks must be unlocked Thread are expensive and their lifecycle management is error prone Traditional problem: Dining Philosophers
Threads do not compose, or interact using exceptions, they all have their own stacktrace.Communicating between threadgroups is not possible using traditional exceptions. Roll your own.You will need to use concurrent data structures to communicate with the threads, like queues for instance.
Can’t I just get these really smart compiler and runtime guys to do parallelization behind the scenes?Gimme that shiny box!
Event driven – The world is event drivenScalable – use both more cores and nodesAsynchronous – Waiting is a bad way to use processing cycle. Life is too short to block.Resilient – More robust and easier failure handling of concurrent and distributed systems
Single Node, Single ThreadLMAX Disruptor, runs on one thread, achieves 100.000 tpsNode.Js (Javascript is singlethreaded) But what if that one thread blocks, or fails..Scale up by just running more processes, but how do you coordinate concurrency?Processes are heavier than threads, and maybe there is even something lighter…Many Nodes, Single ThreadedCombine the single thread processes with some kind of network communication, Like 0MQ, RabbitMQ, ..MQ. Distributed Coordination can be done with a distributed database, or something like Apache Zookeeper.Which are all technologies that live on a diffferent planet, which you will have to master. If need be OK, but this is getting complex.Single Node, Many ThreadsWhat if we just use java.util.concurrent? Concurrent data structures, directly using Threads, locks, semaphores? How hard can deadlocks, livelocks, thread starvation, race conditions really be to debug?Many Nodes, Many Threads.A combination of even more technologies?
Today we are only going to talk about actors, unless we have time left.
One at a time. Sequential in the small. Concurrent and Async in large numbers.
At Restart the new actor instance gets to handle next messages.There is an option to handle the message that was being processed during the crash.
Today we are only going to talk about actors, unless we have time left.
Today we are only going to talk about actors, unless we have time left.
Today we are only going to talk about actors, unless we have time left.
A Service sends subscription based messages using traditional Network I/O. Async because one consumer must not block others. Below Subscription X type messages are sent to consumers.Threads do not compose, or interact using exceptions, they all have their own stacktrace.Communicating between threadgroups is not possible using traditional exceptions. Roll your own.You will need to use concurrent data structures to communicate with the threads, like queues for instance.You can’t guarantee that a thread will be able to handle all possible errors itself, without knowing information about the bigger system or larger context.(network usage policy, behavior of consumer across subsystems could mean the difference between cutting the consumer off, or restarting transmissions To a different endpoint)
A Service sends subscription based messages using traditional Network I/O. Async because one consumer must not block others. Below Subscription X type messages are sent to consumers.Threads do not compose, or interact using exceptions, they all have their own stacktrace.Communicating between threadgroups is not possible using traditional exceptions. Roll your own.You will need to use concurrent data structures to communicate with the threads, like queues for instance.You can’t guarantee that a thread will be able to handle all possible errors itself, without knowing information about the bigger system or larger context.(network usage policy, behavior of consumer across subsystems could mean the difference between cutting the consumer off, or restarting transmissions To a different endpoint)
A Service sends subscription based messages using traditional Network I/O. Async because one consumer must not block others. Below Subscription X type messages are sent to consumers.Threads do not compose, or interact using exceptions, they all have their own stacktrace.Communicating between threadgroups is not possible using traditional exceptions. Roll your own.You will need to use concurrent data structures to communicate with the threads, like queues for instance.You can’t guarantee that a thread will be able to handle all possible errors itself, without knowing information about the bigger system or larger context.(network usage policy, behavior of consumer across subsystems could mean the difference between cutting the consumer off, or restarting transmissions To a different endpoint)
A Service sends subscription based messages using traditional Network I/O. Async because one consumer must not block others. Below Subscription X type messages are sent to consumers.Threads do not compose, or interact using exceptions, they all have their own stacktrace.Communicating between threadgroups is not possible using traditional exceptions. Roll your own.You will need to use concurrent data structures to communicate with the threads, like queues for instance.You can’t guarantee that a thread will be able to handle all possible errors itself, without knowing information about the bigger system or larger context.(network usage policy, behavior of consumer across subsystems could mean the difference between cutting the consumer off, or restarting transmissions To a different endpoint)