SlideShare a Scribd company logo
1 of 146
Download to read offline
Akka and the Zen of Reactive
System Design
by Konrad Malawski (@ktosopl)
Konrad `@ktosopl` Malawski
akka.io
typesafe.com
geecon.org
Java.pl / KrakowScala.pl
sckrk.com / meetup.com/Paper-Cup @ London
GDGKrakow.pl
lambdakrk.pl
Why such talk?
1 : One actor is no Actor
2 : Structure your Actors
3 : Name your Actors
4 : ”Matrix of mutability (Pain)”
5 : Blocking needs careful management
6 : Never Await, for/flatMap instead!
7 : Avoid Java Serialization
7.5 : Trust no-one, benchmark everything!
Agenda
8 : Let it Crash!
9 : Backoff Supervision
10 : Design using State Machines
11 : Cluster Convergence and Joining
12 : Cluster Partitions and “Down”
13 : Akka is a Toolkit.
14 : Happy Hakking, Community!
Questions?
“The Tao / Zen of Programming”
Talk title loosely based on
the “Tao of Programming” book
by Goeffrey James (1987).
“The Tao / Zen of Programming”
And the follow-up book
“Zen of Programming”.
“The Tao / Zen of Programming”
Available here: http://www.mit.edu/~xela/tao.html
Series of nine “books”,
stories about an apprentice programmer and his sensei.
Thus spake the Master Programmer:
“Without the wind, the grass does not move.
Without software hardware is useless.”
The Akka landscape
The Akka landscape
Akka
Actor
IO
Cluster
Cluster Tools (PubSub, Sharding, …)
Persistence & Persistence Query
Streams
HTTP
Typed
The Zen of Akka
Is best explained as a way of thinking about Architecture.
Akka provides building blocks, with specific semantics.
The Zen of Akka
Is best explained as a way of thinking about Architecture.
Akka provides building blocks, with specific semantics.
Actors are cheap – so they can be 1:1 for a user, or wallet etc
Actors are referentially transparent – can scale-out trivially
Actors encapsulate state – avoiding global state
Actors are engines –
Streams / Streaming HTTP / Cluster Sharding / Distributed Data…
– all using are Actors as engines, high-level Architectural help.
1 : One actor is no Actor
1 : One actor is no Actor
1 : One actor is no Actor
If you have only one actor then it can only…
1. Reply
2. Drop the message (“ignore”
3. Schedule another message to self
So we’re not really making any use of its
parallelism or concurrency capabilities.
1 : One actor is no Actor
1 : One actor is no Actor
1 : One actor is no Actor
1 : One actor is no Actor
1 : One actor is no Actor
1 : One actor is no Actor
- Actors are meant to work together.
- An Actor should do one thing and do it very well
- then talk to other Actors to do other things for it.

- Child Actors usually used for workers or “tasks” etc.

- Avoid using `actorSelection`,

introduce Actors to each other.
2 : Structure your Actors
2 : Structure your Actors
Different types…
but no structure!
2 : Structure your Actors
Parent / child relationships
also allow for Actor supervision.
2 : Structure your Actors
3 : Name your Actors
3 : Name your Actors
// default
context.actorOf(childProps) // "$a", "$b", "$c"
Default names are: BASE64(sequence_nr++)
Here’s why:
- cheap to generate
- guarantees uniqueness
- less chars than plain numbers
3 : Name your Actors
// default: naming is BASE64(sequential numbers)
context.actorOf(childProps) // "$a", "$b", "$c"
// better: but not very informative...
context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2"
private var _fetchWorkers: Int = 0
private def nextFetchWorkerName: String = {
_fetchWorkers += 1
s”fetch-worker-${_fetchWorkers}”
}
Sequential names are a bit better sometimes.
3 : Name your Actors
// default: naming is BASE64(sequential numbers)
context.actorOf(childProps) // "$a", "$b", "$c"
// better: but not much informative...
context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2"
private var _fetchWorkers: Int = 0
private def nextFetchWorkerName: String = {
_fetchWorkers += 1
s”fetch-worker-${_fetchWorkers}”
}
abstract class SeqActorName {
def next(): String
def copy(name: String): SeqActorName
}
object SeqActorName {
def apply(prefix: String) = new SeqActorNameImpl(prefix, new AtomicLong(0))
}
final class SeqActorNameImpl(val prefix: String, counter: AtomicLong)
extends SeqActorName {
def next(): String = prefix + '-' + counter.getAndIncrement()
def copy(newPrefix: String): SeqActorName = new SeqActorNameImpl(newPrefix, counter)
}
If you use this pattern a lot, here’s a simple encapsulation of it:
3 : Name your Actors
// default: naming is BASE64(sequential numbers)
context.actorOf(childProps) // "$a", "$b", "$c"
// better: but not much informative...
context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2"
private var fetchWorkers: Int = 0
private def nextFetchWorkerName: String = {
fetchWorkers += 1
s"fetch-worker-$fetchWorkers"
}
// BEST: proper names, based on useful information
context.actorOf(childProps, fetcherName(videoUrl)) // "fetch-yt-MRCWy2E_Ts", ...
def fetcherName(link: Link) = link match {
case YoutubeLink(id, metadata) => s"fetch-yt-$id"
case DailyMotionLink(id, metadata) => s"fetch-dm-$id"
case VimeoLink(id, metadata) => s"fetch-vim-$id"
}
Meaningful names are the best!
3 : Name your Actors
Meaningful names are the best!
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
// ... extends Actor with ActorLogging {
override def supervisorStrategy: SupervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) {
case ex: Exception
log.warning("Child {} failed with {}, attempting restart...",
sender().path.name,
ex.getMessage)
Restart
}
The name of the failed child Actor!
3 : Name your Actors
Meaningful names are the best!
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy._
import scala.concurrent.duration._
// ... extends Actor with ActorLogging {
override def supervisorStrategy: SupervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) {
case ex: Exception
log.warning("Child {} failed with {}, attempting restart...",
sender().path.name,
ex.getMessage)
Restart
}
The name of the failed child Actor!
// BAD –– String ALWAYS built
log.debug(s"Something heavy $generateId from $physicalAddress")
// GOOD! –– String built only when DEBUG level is ON
log.debug("Something heavy {} from {}", generateId, physicalAddress)
Side note: always use {} log formatting (or macros), not s””
4 : ”Matrix of mutability (Pain)”
4 : ”Matrix of mutability (Pain)”
See Jamie Allen’s talk on the subject.
4 : ”Matrix of mutability (Pain)”
See Jamie Allen’s talk on the subject.
4 : ”Matrix of mutability (Pain)”
See Jamie Allen’s talk on the subject.
4 : ”Matrix of mutability (Pain)”
See Jamie Allen’s talk on the subject.
4 : ”Matrix of mutability (Pain)”
See Jamie Allen’s talk on the subject.
4 : ”Matrix of mutability (Pain)”
5 : Blocking needs careful management
5 : Blocking needs careful management
Blocking operations are really bad.
Actors are all about resource sharing, and if someone is “behaving
badly” it hurts everyone.
Here is an example how blocking can grind an app to a halt.
Next we’ll see how to avoid that… even if we have to live with the
blocking code.
5 : Blocking needs careful management
In simple terms:
Blocking is bad because instead of doing something else,
we just wait and do nothing (wasting CPU time)…
5 : Blocking needs careful management
5 : Blocking needs careful management
Having that said, it’s not a bad question. Let’s investigate.
5 : Blocking needs careful management
// BAD! (due to the blocking in Future):
implicit val defaultDispatcher = system.dispatcher
val routes: Route = post {
complete {
Future { // uses defaultDispatcher
Thread.sleep(5000) // will block on the default dispatcher,
System.currentTimeMillis().toString // starving the routing infra
}
}
}
5 : Blocking needs careful management
// BAD! (due to the blocking in Future):
implicit val defaultDispatcher = system.dispatcher
val routes: Route = post {
complete {
Future { // uses defaultDispatcher
Thread.sleep(5000) // will block on the default dispatcher,
System.currentTimeMillis().toString // starving the routing infra
}
}
}
5 : Blocking needs careful management
// application.conf
my-blocking-dispatcher {
type = Dispatcher
executor = “thread-pool-executor"
thread-pool-executor {
// in Akka previous to 2.4.2:
core-pool-size-min = 16
core-pool-size-max = 16
max-pool-size-min = 16
max-pool-size-max = 16
// or in Akka 2.4.2+
fixed-pool-size = 16
}
throughput = 100
}
5 : Blocking needs careful management
// GOOD (due to the blocking on a dedicated dispatcher):
implicit val blockingDispatcher = system.dispatchers.lookup("my-blocking-dispatcher")
val routes: Route = post {
complete {
Future { // uses the good "blocking dispatcher" that we configured,
// instead of the default dispatcher – the blocking is isolated.
Thread.sleep(5000)
System.currentTimeMillis().toString
}
}
}
5 : Blocking needs careful management
The “Never block!” mantra sounds cool,
but actually what we mean by it is “blocking needs careful management”.
We use the “bulkhead” pattern separate out potentially blocking
behaviours to their independent dispatchers (and should always do so).
http://stackoverflow.com/questions/34641861/akka-http-blocking-in-a-future-blocks-the-server/34645097#34645097
6 : Never Await, for/flatMap instead!
6 : Never Await, for/flatMap instead!
// ... extends Actor {
import context.dispatcher
import scala.concurrent.duration._
import scala.concurrent.Await // bad sign!
// BAD!!!
val fThings: Future[Things] = computeThings()
val t: Things = Await.result(fThings, atMost = 3.seconds)
val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds)
6 : Never Await, for/flatMap instead!
// ... extends Actor {
import context.dispatcher
import scala.concurrent.duration._
import scala.concurrent.Await // bad sign!
// BAD!!!
val fThings: Future[Things] = computeThings()
val t: Things = Await.result(fThings, atMost = 3.seconds)
val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds)
// Good:
val fThingsWithDetails = for {
t <- computeThings()
d <- moreDetailsFor(t)
} yield t -> d
fThingsWithDetails foreach {
case (things, details) => // case (things: Things, details: Details) =>
println(s"$things with $details")
}
6 : Never Await, for/flatMap instead!
// ... extends Actor {
import context.dispatcher
import scala.concurrent.duration._
import scala.concurrent.Await // bad sign!
// BAD!!!
val fThings: Future[Things] = computeThings()
val t: Things = Await.result(fThings, atMost = 3.seconds)
val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds)
// Good:
val fThingsWithDetails = for {
t <- computeThings()
d <- moreDetailsFor(t)
} yield t -> d
fThingsWithDetails foreach {
case (things, details) => // case (things: Things, details: Details) =>
println(s"$things with $details")
}
// adding timeout:
val timeoutFuture = akka.pattern.after(3.seconds, context.system.scheduler) {
Future.failed(new TimeoutException("My timeout details..."))
}
Future.firstCompletedOf(fThingsWithDetails :: timeoutFuture :: Nil) foreach {
case (things, details) => // case (things: Things, details: Details) =>
println(s"$things with $details")
}
7 : Avoid Java Serialization
7 : Avoid Java Serialization
Java Serialization is the default one in Akka, since it’s easy to
get started with it – no configuration needed.
If you need performance and are running on multiple nodes,
you must change the serialization.
Popular formats are ProtoBuf or Kryo.
Kryo is easier, but harder to evolve schema with.
ProtoBuf is harder to maintain but great schema evolution.
7 : Avoid Java Serialization
Benchmarking serialization impact on “ping pong” case.
(Two actors sending a message between them.)
in-process messaging, super fast.

no serialization overhead.
7 : Avoid Java Serialization
more work => increased latency => decreased throughput.
over-the-network messaging,
slower due to network and serialization.
7 : Avoid Java Serialization
Java Serialization is known to be:
very slow & footprint heavy
7 : Avoid Java Serialization
It is on by default in Akka… Why?
a) zero setup => simple to “play around”
b) historical reasons - hard to remove the default
Since 2.4 a warning is logged:

WARNING: Using the default Java serializer for class [{}] which is not recommended
because of performance implications. Use another serializer or disable this warning
using the setting 'akka.actor.warn-about-java-serializer-usage'
7 : Avoid Java Serialization
sbt> jmh:run 

-f 1
-tu us 

-wi 20
-i 10
-jvm /home/ktoso/opt/jdk1.8.0_65/bin/java
-jvmArgsAppend -XX:+PreserveFramePointer
-bm avgt
.*pingPong.*
[info] # JMH 1.10.3 (released 184 days ago, please consider updating!)
[info] # VM version: JDK 1.8.0_65, VM 25.65-b01
[info] # VM invoker: /home/ktoso/opt/jdk1.8.0_65/bin/java
[info] # VM options: -XX:+PreserveFramePointer
[info] # Warmup: 20 iterations, 5 s each
[info] # Measurement: 10 iterations, 1 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread, will synchronize iterations
[info] # Benchmark mode: Average time, time/op
[info] # Benchmark: akka.actor.ForkJoinActorBenchmark.pingPong
[info] # Parameters: (serializer = java)
github.com/ktoso/sbt-jmh
openjdk.java.net/projects/code-tools/jmh/
7 : Avoid Java Serialization
[info] # Warmup Iteration 1: 35.717 us/op
. . .
[info] # Warmup Iteration 19: 25.164 us/op
[info] # Warmup Iteration 20: 23.862 us/op
[info] Iteration 1: 25.790 us/op
. . .
[info] Iteration 10: 26.168 us/op


[info] Result "pingPong":
[info] 25.464 ±(99.9%) 1.175 us/op [Average]
[info] (min, avg, max) = (24.383, 25.464, 26.888), stdev = 0.777
[info] CI (99.9%): [24.289, 26.639] (assumes normal distribution)
[info] ForkJoinActorBenchmark.pingPong java avgt 10 25.464 ± 1.175 us/op
[info] ForkJoinActorBenchmark.pingPong off avgt 10 0.967 ± 0.657 us/op
github.com/ktoso/sbt-jmh
openjdk.java.net/projects/code-tools/jmh/
7 : Avoid Java Serialization
Good serializers include (but are not limited to):
Kryo, Google Protocol Buffers, SBE,Thrift, JSON even (sic!)
// dependencies
"com.github.romix.akka" %% "akka-kryo-serialization" % "0.4.0"
// application.conf
extensions = [“com.romix.akka.serialization.kryo.KryoSerializationExtension$"]


serializers { 

java = "akka.serialization.JavaSerializer"
kryo = "com.romix.akka.serialization.kryo.KryoSerializer" 

}
akka.actor.serialization-bindings {
“com.mycompany.Example”: kryo
. . .
}
[info] ForkJoinActorBenchmark.pingPong java avgt 10 25.464 ± 1.175 us/op
[info] ForkJoinActorBenchmark.pingPong kryo avgt 10 4.348 ± 4.346 us/op
[info] ForkJoinActorBenchmark.pingPong off avgt 10 0.967 ± 0.657 us/op
7 : Avoid Java Serialization
----sr--model.Order----h#-----J--idL--customert--Lmodel/Customer;L--descriptiont--Ljava/lang/String;L--orderLinest--Ljava/util/List;L--totalCostt--Ljava/
math/BigDecimal;xp--------ppsr--java.util.ArrayListx-----a----I--sizexp----w-----sr--model.OrderLine--&-1-S----I--lineNumberL--costq-~--L--descriptionq-
~--L--ordert--Lmodel/Order;xp----sr--java.math.BigDecimalT--W--(O---I--scaleL--intValt--Ljava/math/BigInteger;xr--java.lang.Number-----------xp----sr--
java.math.BigInteger-----;-----I--bitCountI--bitLengthI--firstNonzeroByteNumI--lowestSetBitI--signum[--magnitudet--[Bxq-~----------------------ur--[B------
T----xp----xxpq-~--xq-~--
Java Serialization
final case class Order(id: Long, description: String, totalCost: BigDecimal,
orderLines: ArrayList[OrderLines], customer: Customer)
<order id="0" totalCost="0"><orderLines lineNumber="1" cost="0"><order>0</order></orderLines></order>XML…!
{"order":{"id":0,"totalCost":0,"orderLines":[{"lineNumber":1,"cost":0,"order":0}]}}JSON…!
------java-util-ArrayLis-----model-OrderLin----java-math-BigDecima---------model-Orde-----Kryo…!
Excellent post by James Sutherland @
http://java-persistence-performance.blogspot.com/2013/08/optimizing-java-serialization-java-vs.html
7 : Avoid Java Serialization for Persistence!!!
Java Serialization is a horrible idea if you’re going to store the
messages for a long time.
For example, with Akka Persistence we store events “forever”.
Use a serialization format that can evolve over time in a
compatible way. It can be JSON or ProtocolBuffers (or Thrift
etc).
7.5 : Trust no-one, benchmark everything!
Always measure and benchmark properly
before judging performance of a tool / library.
Benchmarking is often very hard,
use the right tools:
- JMH (for Scala via: ktoso/sbt-jmh)
-YourKit / JProfiler / …
- Linux perf_events
7.5
8 : Let it Crash! Supervision, Failures & Errors
http://www.reactivemanifesto.org/
8 : Let it Crash! Supervision, Failures & Errors
Error
… which is an expected and coded-for condition—for
example an error discovered during input validation, that
will be communicated to the client …
Failure
… is an unexpected event within a service that
prevents it from continuing to function normally. 

A failure will generally prevent responses to the current,
and possibly all following, client requests.
http://www.reactivemanifesto.org/
8 : Let it Crash! Supervision, Failures &
http://www.reactivemanifesto.org/
8 : Let it Crash! Supervision, Failures & Errors
http://www.reactivemanifesto.org/
8 : Let it Crash! Supervision, Failures & Errors
Error: “Not enough cash.”
http://www.reactivemanifesto.org/
8 : Let it Crash! Supervision, Failures & Errors
Error: “Unable to fulfil request”
Failure: “Row 3 is broken”
9 : Backoff Supervision
9 : Backoff Supervision
9 : Backoff Supervision
9 : Backoff Supervision
9 : Backoff Supervision
Our goal is to “let things crash”
and “recover gracefully”
Not to hammer the DB while it tries to recover!
9 : Backoff Supervision
9 : Backoff Supervision
9 : Backoff Supervision
IF we allowed immediate restarts…
we could end up in “infinite replay+fail hell”.
(we don’t. since Persistence went stable in 2.4.x)
9 : Backoff Supervision
9 : Backoff Supervision
Many PersistentActors Fail and Stop.
9 : Backoff Supervision
9 : Backoff Supervision
Backoff Supervisor counts failures
and starts “the same” entity after
exponential timeouts.
9 : Backoff Supervision
10 : Design using State Machines
10 : Design using State Machines
def receive = {
case Thingy() =>
// ...
case AnotherThingy() =>
// ...
case DoOtherThings() =>
// ...
case PleaseGoAway() =>
// ...
case CarryOn() =>
// ...
case MakeSomething() =>
// ...
// ...
}
10 : Design using State Machines
def receive = {
case Thingy() =>
// ...
case AnotherThingy() =>
// ...
case DoOtherThings() =>
// ...
case PleaseGoAway() =>
// ...
case CarryOn() =>
// ...
case MakeSomething() =>
// ...
// ...
}
Good:
Actors avoid the “pyramid of doom”.
Pyramid of doom in some
async programming styles.
10 : Design using State Machines
def receive = {
case Thingy() =>
// ...
case AnotherThingy() =>
// ...
case DoOtherThings() =>
// ...
case PleaseGoAway() =>
// ...
case CarryOn() =>
// ...
case MakeSomething() =>
// ...
// ...
}
That well works because
“everything is a message”:
10 : Design using State Machines
def receive = awaitingInstructions
def awaitingInstructions: Receive =
terminationHandling orElse {
case CarryOn() =>
// ...
case MakeSomething(metadata) =>
// ...
context become makeThings(meta)
}
def makeThings(metadata: Metadata): Receive =
terminationHandling orElse {
case Thingy() =>
// make a thingy ...
case AnotherThingy() =>
// make another thingy ...
case DoOtherThings(meta) =>
// ...
context become awaitingInstructions
}
def terminationHandling: Receive = {
case PleaseGoAway() =>
// ...
context stop self
}
DoOtherThings
MakeSomething
10 : Design using State Machines
We also provide an FSM (Finite State Machine) helper trait.
You may enjoy it sometimes, give it a look.
DoOtherThings
MakeSomething
http://doc.akka.io/docs/akka/2.4.1/scala/fsm.html
class Buncher extends FSM[State, Data] {
startWith(Idle, Uninitialized)
when(Idle) {
case Event(SetTarget(ref), Uninitialized) =>
stay using Todo(ref, Vector.empty)
}
// transition elided ...
when(Active, stateTimeout = 1 second) {
case Event(Flush | StateTimeout, t: Todo) =>
goto(Idle) using t.copy(queue = Vector.empty)
}
// unhandled elided ...
initialize()
}
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
Cluster Gossip Convergence
When a node can prove that the cluster state it is observing
has been observed by all other nodes in the cluster.
11 : Cluster Convergence and Joining
http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
Cluster Gossip Convergence
When a node can prove that the cluster state it is observing
has been observed by all other nodes in the cluster.
Convergence is required for “Leader actions”,
which include Join-ing and Remove-ing a node.
Down-ing can happen without convergence.
11 : Cluster Convergence and Joining
http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
11 : Cluster Convergence and Joining
http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
akka.cluster.allow-weakly-up-members=on
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
11 : Cluster Convergence and Joining
Everyone has ‘seen’
Kurt joining,
move him to Up.
11 : Cluster Convergence and Joining
Kurt is now with us
in the Cluster.
11 : Cluster Convergence and Joining
I can’t hear Kurt…
He’s unreachable…
11 : Cluster Convergence and Joining
Kurt does has not
seen Rei… I can not
mark him as Up!
allow-weakly-up-members=off // default
11 : Cluster Convergence and Joining
I’ll mark Rei as
“WeaklyUp” until Kurt
is back.
allow-weakly-up-members=on
allow-weakly-up-members
11 : Cluster Convergence and Joining
Kurt is back! Once he
has seen Rei I’ll mark
Rei as Up.
allow-weakly-up-members=on
allow-weakly-up-members
12 : Cluster Partitions and “Down”
12 : Cluster Partitions and “Down”
12 : Cluster Partitions and “Down”
I’m going
home…
12 : Cluster Partitions and “Down”
Make sure the others have heard you say goodbye before you leave.
Vanishes immediately.
12 : Cluster Partitions and “Down”
Make sure the others have heard you say goodbye before you leave.
“Where’s Bill?
I did not hear him say Goodbye!”
“Failure Detector” used to determine UNREACHABLE.
12 : Cluster Partitions and “Down”
Failure detection only triggers “UNREACHABLE”.
Nodes can come back from that state.
12 : Cluster Partitions and “Down”
Declaring DOWN is done by either timeouts (which is rather unsafe) [auto-downing].
Or by “voting” or “majority” among the members of the cluster [split-brain-resolver].
12 : Cluster Partitions and “Down”
12 : Cluster Partitions and “Down”
お
前
は
も
う
死
ん
で
い
る
.
.
.
.
Node declared “DOWN” comes back…
12 : Cluster Partitions and “Down”
You
are
already
dead.
12 : Cluster Partitions and “Down”Why do we do that?
In order to guarantee consistency via
“single writer principle”.
Note:
Akka Distributed Data has no need for “single
writer”, it’s CRDT based. But it’s harder to model
things as CRDT, so it’s a trade off.
You
are
already
dead.
12 : Cluster Partitions and “Down”
Notice that we do not mention “Quarantined”.
That is a state in Akka Remoting, not Cluster.
It’s a terminal state from which one can never recover.
TL;DR;
use Akka Cluster instead of Remoting.
it’s pretty much always the thing you need (better than remoting).
13 : A fishing rod is a Tool. Akka is a Toolkit.
13 : A fishing rod is a Tool. Akka is a Toolkit.
Akka strives is Toolkit,
not a Framework.
“Give a man a fish and you feed him for a day
teach a man to fish and you feed him for a lifetime.”
13 : A fishing rod is a Tool. Akka is a Toolkit.
Akka strives is Toolkit,
not a Framework.
Play is a Framework,
Lagom is a Framework.
13 : Akka is a Toolkit, pick the right tools for the job.
“Constraints Liberate,
Liberties Constrain”
Runar Bjarnason
Runar’s excellent talk @ Scala.World 2015
13 : Akka is a Toolkit, pick the right tools for the job.
Runar’s excellent talk @ Scala.World 2015
The less powerful abstraction
must be built on top of
more powerful abstractions.
13 : Akka is a Toolkit, pick the right tools for the job.
Runar’s excellent talk @ Scala.World 2015
Asynchronous processing toolbox:
13 : Akka is a Toolkit, pick the right tools for the job.
Runar’s excellent talk @ Scala.World 2015
Asynchronous processing toolbox:
13 : Akka is a Toolkit, pick the right tools for the job.
Asynchronous processing toolbox:
13 : Akka is a Toolkit, pick the right tools for the job.
Single value, no streaming by definition.
Local abstraction.

Execution contexts.
13 : Akka is a Toolkit, pick the right tools for the job.
Mostly static processing layouts.
Well typed and Back-pressured!
13 : Akka is a Toolkit, pick the right tools for the job.
Plain Actor’s younger brother, experimental.
Location transparent, well typed.
Technically unconstrained in actions performed
13 : Akka is a Toolkit, pick the right tools for the job.
Runar’s excellent talk @ Scala.World 2015
Location transparent.
Various resilience mechanisms.
(watching, persistent recovering, migration, pools)
Untyped and unconstrained in actions performed.
13 : Picking the tools – distributing / sharding processing
Runar’s excellent talk @ Scala.World 2015
13 : Picking the tools – distributing / sharding processing
Runar’s excellent talk @ Scala.World 2015Whitepaper by Pat Helland, 2005

http://cidrdb.org/cidr2005/papers/P12.pdf
13 : Picking the tools – “element by element” processing
Runar’s excellent talk @ Scala.World 2015
// types: _
Source[Int, Unit]
Flow[Int, String, Unit]
Sink[String, Future[String]]
Source.single(1).map(_.toString).runWith(Sink.head)
13 : Picking the tools – streaming HTTP APIs
13 : Picking the tools – streaming HTTP APIs
13 : Picking the tools – streaming HTTP APIs
13 : Picking the tools – streaming HTTP APIs
No demand from TCP
=
No demand upstream
=
Source won’t generate tweets
13 : Picking the tools – streaming HTTP APIs
No demand from TCP
=
No demand upstream
=
Source won’t generate tweets
=>
13 : Picking the tools – streaming HTTP APIs
No demand from TCP
=
No demand upstream
=
Source won’t generate tweets
=>
Bounded memory
stream processing!
13 : Picking the tools – streaming HTTP APIs
14 : Happy hAkking, Community!
14 : Happy hAkking, Community!
akka.io – website
github.com/akka/akka/issues – help out!
“community-contrib” or “small” for starters
groups.google.com/group/akka-user – mailing list
gitter.im/akka/akka – chat about using Akka
gitter.im/akka/dev – chat about developing Akka
Links
• http://stackoverflow.com/questions/34641861/akka-http-blocking-
in-a-future-blocks-the-server/34645097#34645097
• The wonderful Zen paintings to buy here:

http://paintingwholesalechina.com/products/chinese-culture-zen-
no-1-academic-chinese-painting
• http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
• http://www.mit.edu/~xela/tao.html
• http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
• http://doc.akka.io/docs/akka/2.4.1/scala/cluster-usage.html
• akka.io et al.
Thanks!
ktoso @ typesafe.com
twitter: ktosopl
github: ktoso
team blog: letitcrash.com
home: akka.io
Thus spake the Master Programmer:
“After three days without programming,
life becomes meaningless.”
lightbend.com/contact
Reactive Roundtable
World Tour by Lightbend
lightbend.com/reactive-roundtable
PoV/Pilot
Enablement

Accelerate Project Success
©Typesafe 2016 – All Rights Reserved

More Related Content

What's hot

Concurrency in Scala - the Akka way
Concurrency in Scala - the Akka wayConcurrency in Scala - the Akka way
Concurrency in Scala - the Akka way
Yardena Meymann
 

What's hot (20)

Introduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users GroupIntroduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users Group
 
Advanced akka features
Advanced akka featuresAdvanced akka features
Advanced akka features
 
Akka Futures and Akka Remoting
Akka Futures  and Akka RemotingAkka Futures  and Akka Remoting
Akka Futures and Akka Remoting
 
55 New Features in Java 7
55 New Features in Java 755 New Features in Java 7
55 New Features in Java 7
 
The dark side of Akka and the remedy
The dark side of Akka and the remedyThe dark side of Akka and the remedy
The dark side of Akka and the remedy
 
Actor Model Akka Framework
Actor Model Akka FrameworkActor Model Akka Framework
Actor Model Akka Framework
 
React Native Evening
React Native EveningReact Native Evening
React Native Evening
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Django REST Framework
Django REST FrameworkDjango REST Framework
Django REST Framework
 
First glance at Akka 2.0
First glance at Akka 2.0First glance at Akka 2.0
First glance at Akka 2.0
 
Concurrency in Scala - the Akka way
Concurrency in Scala - the Akka wayConcurrency in Scala - the Akka way
Concurrency in Scala - the Akka way
 
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developersSoftshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesDjangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
 

Similar to Akka and the Zen of Reactive System Design

Intro to scala
Intro to scalaIntro to scala
Intro to scala
Joe Zulli
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Konrad Malawski
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
Douglas Crockford Presentation Goodparts
Douglas Crockford Presentation GoodpartsDouglas Crockford Presentation Goodparts
Douglas Crockford Presentation Goodparts
Ajax Experience 2009
 

Similar to Akka and the Zen of Reactive System Design (20)

Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Intro to scala
Intro to scalaIntro to scala
Intro to scala
 
The things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and AkkaThe things we don't see – stories of Software, Scala and Akka
The things we don't see – stories of Software, Scala and Akka
 
Akka Actors: an Introduction
Akka Actors: an IntroductionAkka Actors: an Introduction
Akka Actors: an Introduction
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Writing a REST Interconnection Library in Swift
Writing a REST Interconnection Library in SwiftWriting a REST Interconnection Library in Swift
Writing a REST Interconnection Library in Swift
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Goodparts
GoodpartsGoodparts
Goodparts
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
jQuery Anti-Patterns for Performance
jQuery Anti-Patterns for PerformancejQuery Anti-Patterns for Performance
jQuery Anti-Patterns for Performance
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 
55j7
55j755j7
55j7
 
55 new things in Java 7 - Devoxx France
55 new things in Java 7 - Devoxx France55 new things in Java 7 - Devoxx France
55 new things in Java 7 - Devoxx France
 
Swift - ARC와 메모리 관리
Swift - ARC와 메모리 관리Swift - ARC와 메모리 관리
Swift - ARC와 메모리 관리
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Douglas Crockford Presentation Goodparts
Douglas Crockford Presentation GoodpartsDouglas Crockford Presentation Goodparts
Douglas Crockford Presentation Goodparts
 
Play framework
Play frameworkPlay framework
Play framework
 
Everything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-insEverything is Permitted: Extending Built-ins
Everything is Permitted: Extending Built-ins
 

More from Lightbend

More from Lightbend (20)

IoT 'Megaservices' - High Throughput Microservices with Akka
IoT 'Megaservices' - High Throughput Microservices with AkkaIoT 'Megaservices' - High Throughput Microservices with Akka
IoT 'Megaservices' - High Throughput Microservices with Akka
 
How Akka Cluster Works: Actors Living in a Cluster
How Akka Cluster Works: Actors Living in a ClusterHow Akka Cluster Works: Actors Living in a Cluster
How Akka Cluster Works: Actors Living in a Cluster
 
The Reactive Principles: Eight Tenets For Building Cloud Native Applications
The Reactive Principles: Eight Tenets For Building Cloud Native ApplicationsThe Reactive Principles: Eight Tenets For Building Cloud Native Applications
The Reactive Principles: Eight Tenets For Building Cloud Native Applications
 
Putting the 'I' in IoT - Building Digital Twins with Akka Microservices
Putting the 'I' in IoT - Building Digital Twins with Akka MicroservicesPutting the 'I' in IoT - Building Digital Twins with Akka Microservices
Putting the 'I' in IoT - Building Digital Twins with Akka Microservices
 
Akka at Enterprise Scale: Performance Tuning Distributed Applications
Akka at Enterprise Scale: Performance Tuning Distributed ApplicationsAkka at Enterprise Scale: Performance Tuning Distributed Applications
Akka at Enterprise Scale: Performance Tuning Distributed Applications
 
Digital Transformation with Kubernetes, Containers, and Microservices
Digital Transformation with Kubernetes, Containers, and MicroservicesDigital Transformation with Kubernetes, Containers, and Microservices
Digital Transformation with Kubernetes, Containers, and Microservices
 
Detecting Real-Time Financial Fraud with Cloudflow on Kubernetes
Detecting Real-Time Financial Fraud with Cloudflow on KubernetesDetecting Real-Time Financial Fraud with Cloudflow on Kubernetes
Detecting Real-Time Financial Fraud with Cloudflow on Kubernetes
 
Cloudstate - Towards Stateful Serverless
Cloudstate - Towards Stateful ServerlessCloudstate - Towards Stateful Serverless
Cloudstate - Towards Stateful Serverless
 
Digital Transformation from Monoliths to Microservices to Serverless and Beyond
Digital Transformation from Monoliths to Microservices to Serverless and BeyondDigital Transformation from Monoliths to Microservices to Serverless and Beyond
Digital Transformation from Monoliths to Microservices to Serverless and Beyond
 
Akka Anti-Patterns, Goodbye: Six Features of Akka 2.6
Akka Anti-Patterns, Goodbye: Six Features of Akka 2.6Akka Anti-Patterns, Goodbye: Six Features of Akka 2.6
Akka Anti-Patterns, Goodbye: Six Features of Akka 2.6
 
Lessons From HPE: From Batch To Streaming For 20 Billion Sensors With Lightbe...
Lessons From HPE: From Batch To Streaming For 20 Billion Sensors With Lightbe...Lessons From HPE: From Batch To Streaming For 20 Billion Sensors With Lightbe...
Lessons From HPE: From Batch To Streaming For 20 Billion Sensors With Lightbe...
 
How to build streaming data pipelines with Akka Streams, Flink, and Spark usi...
How to build streaming data pipelines with Akka Streams, Flink, and Spark usi...How to build streaming data pipelines with Akka Streams, Flink, and Spark usi...
How to build streaming data pipelines with Akka Streams, Flink, and Spark usi...
 
Microservices, Kubernetes, and Application Modernization Done Right
Microservices, Kubernetes, and Application Modernization Done RightMicroservices, Kubernetes, and Application Modernization Done Right
Microservices, Kubernetes, and Application Modernization Done Right
 
Full Stack Reactive In Practice
Full Stack Reactive In PracticeFull Stack Reactive In Practice
Full Stack Reactive In Practice
 
Akka and Kubernetes: A Symbiotic Love Story
Akka and Kubernetes: A Symbiotic Love StoryAkka and Kubernetes: A Symbiotic Love Story
Akka and Kubernetes: A Symbiotic Love Story
 
Scala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To KnowScala 3 Is Coming: Martin Odersky Shares What To Know
Scala 3 Is Coming: Martin Odersky Shares What To Know
 
Migrating From Java EE To Cloud-Native Reactive Systems
Migrating From Java EE To Cloud-Native Reactive SystemsMigrating From Java EE To Cloud-Native Reactive Systems
Migrating From Java EE To Cloud-Native Reactive Systems
 
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming ApplicationsRunning Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
Running Kafka On Kubernetes With Strimzi For Real-Time Streaming Applications
 
Designing Events-First Microservices For A Cloud Native World
Designing Events-First Microservices For A Cloud Native WorldDesigning Events-First Microservices For A Cloud Native World
Designing Events-First Microservices For A Cloud Native World
 
Scala Security: Eliminate 200+ Code-Level Threats With Fortify SCA For Scala
Scala Security: Eliminate 200+ Code-Level Threats With Fortify SCA For ScalaScala Security: Eliminate 200+ Code-Level Threats With Fortify SCA For Scala
Scala Security: Eliminate 200+ Code-Level Threats With Fortify SCA For Scala
 

Recently uploaded

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Recently uploaded (20)

WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 

Akka and the Zen of Reactive System Design

  • 1. Akka and the Zen of Reactive System Design by Konrad Malawski (@ktosopl)
  • 2.
  • 3. Konrad `@ktosopl` Malawski akka.io typesafe.com geecon.org Java.pl / KrakowScala.pl sckrk.com / meetup.com/Paper-Cup @ London GDGKrakow.pl lambdakrk.pl
  • 4. Why such talk? 1 : One actor is no Actor 2 : Structure your Actors 3 : Name your Actors 4 : ”Matrix of mutability (Pain)” 5 : Blocking needs careful management 6 : Never Await, for/flatMap instead! 7 : Avoid Java Serialization 7.5 : Trust no-one, benchmark everything! Agenda 8 : Let it Crash! 9 : Backoff Supervision 10 : Design using State Machines 11 : Cluster Convergence and Joining 12 : Cluster Partitions and “Down” 13 : Akka is a Toolkit. 14 : Happy Hakking, Community! Questions?
  • 5.
  • 6. “The Tao / Zen of Programming” Talk title loosely based on the “Tao of Programming” book by Goeffrey James (1987).
  • 7. “The Tao / Zen of Programming” And the follow-up book “Zen of Programming”.
  • 8. “The Tao / Zen of Programming” Available here: http://www.mit.edu/~xela/tao.html Series of nine “books”, stories about an apprentice programmer and his sensei. Thus spake the Master Programmer: “Without the wind, the grass does not move. Without software hardware is useless.”
  • 10. The Akka landscape Akka Actor IO Cluster Cluster Tools (PubSub, Sharding, …) Persistence & Persistence Query Streams HTTP Typed
  • 11. The Zen of Akka Is best explained as a way of thinking about Architecture. Akka provides building blocks, with specific semantics.
  • 12. The Zen of Akka Is best explained as a way of thinking about Architecture. Akka provides building blocks, with specific semantics. Actors are cheap – so they can be 1:1 for a user, or wallet etc Actors are referentially transparent – can scale-out trivially Actors encapsulate state – avoiding global state Actors are engines – Streams / Streaming HTTP / Cluster Sharding / Distributed Data… – all using are Actors as engines, high-level Architectural help.
  • 13. 1 : One actor is no Actor
  • 14. 1 : One actor is no Actor
  • 15. 1 : One actor is no Actor If you have only one actor then it can only… 1. Reply 2. Drop the message (“ignore” 3. Schedule another message to self So we’re not really making any use of its parallelism or concurrency capabilities.
  • 16. 1 : One actor is no Actor
  • 17. 1 : One actor is no Actor
  • 18. 1 : One actor is no Actor
  • 19. 1 : One actor is no Actor
  • 20. 1 : One actor is no Actor
  • 21. 1 : One actor is no Actor - Actors are meant to work together. - An Actor should do one thing and do it very well - then talk to other Actors to do other things for it.
 - Child Actors usually used for workers or “tasks” etc.
 - Avoid using `actorSelection`,
 introduce Actors to each other.
  • 22. 2 : Structure your Actors
  • 23. 2 : Structure your Actors Different types… but no structure!
  • 24. 2 : Structure your Actors Parent / child relationships also allow for Actor supervision.
  • 25. 2 : Structure your Actors
  • 26. 3 : Name your Actors
  • 27. 3 : Name your Actors // default context.actorOf(childProps) // "$a", "$b", "$c" Default names are: BASE64(sequence_nr++) Here’s why: - cheap to generate - guarantees uniqueness - less chars than plain numbers
  • 28. 3 : Name your Actors // default: naming is BASE64(sequential numbers) context.actorOf(childProps) // "$a", "$b", "$c" // better: but not very informative... context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2" private var _fetchWorkers: Int = 0 private def nextFetchWorkerName: String = { _fetchWorkers += 1 s”fetch-worker-${_fetchWorkers}” } Sequential names are a bit better sometimes.
  • 29. 3 : Name your Actors // default: naming is BASE64(sequential numbers) context.actorOf(childProps) // "$a", "$b", "$c" // better: but not much informative... context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2" private var _fetchWorkers: Int = 0 private def nextFetchWorkerName: String = { _fetchWorkers += 1 s”fetch-worker-${_fetchWorkers}” } abstract class SeqActorName { def next(): String def copy(name: String): SeqActorName } object SeqActorName { def apply(prefix: String) = new SeqActorNameImpl(prefix, new AtomicLong(0)) } final class SeqActorNameImpl(val prefix: String, counter: AtomicLong) extends SeqActorName { def next(): String = prefix + '-' + counter.getAndIncrement() def copy(newPrefix: String): SeqActorName = new SeqActorNameImpl(newPrefix, counter) } If you use this pattern a lot, here’s a simple encapsulation of it:
  • 30. 3 : Name your Actors // default: naming is BASE64(sequential numbers) context.actorOf(childProps) // "$a", "$b", "$c" // better: but not much informative... context.actorOf(childProps, nextFetchWorkerName) // "fetch-worker-1", "fetch-worker-2" private var fetchWorkers: Int = 0 private def nextFetchWorkerName: String = { fetchWorkers += 1 s"fetch-worker-$fetchWorkers" } // BEST: proper names, based on useful information context.actorOf(childProps, fetcherName(videoUrl)) // "fetch-yt-MRCWy2E_Ts", ... def fetcherName(link: Link) = link match { case YoutubeLink(id, metadata) => s"fetch-yt-$id" case DailyMotionLink(id, metadata) => s"fetch-dm-$id" case VimeoLink(id, metadata) => s"fetch-vim-$id" } Meaningful names are the best!
  • 31. 3 : Name your Actors Meaningful names are the best! import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ // ... extends Actor with ActorLogging { override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) { case ex: Exception log.warning("Child {} failed with {}, attempting restart...", sender().path.name, ex.getMessage) Restart } The name of the failed child Actor!
  • 32. 3 : Name your Actors Meaningful names are the best! import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ // ... extends Actor with ActorLogging { override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1.minute) { case ex: Exception log.warning("Child {} failed with {}, attempting restart...", sender().path.name, ex.getMessage) Restart } The name of the failed child Actor! // BAD –– String ALWAYS built log.debug(s"Something heavy $generateId from $physicalAddress") // GOOD! –– String built only when DEBUG level is ON log.debug("Something heavy {} from {}", generateId, physicalAddress) Side note: always use {} log formatting (or macros), not s””
  • 33. 4 : ”Matrix of mutability (Pain)”
  • 34. 4 : ”Matrix of mutability (Pain)” See Jamie Allen’s talk on the subject.
  • 35. 4 : ”Matrix of mutability (Pain)” See Jamie Allen’s talk on the subject.
  • 36. 4 : ”Matrix of mutability (Pain)” See Jamie Allen’s talk on the subject.
  • 37. 4 : ”Matrix of mutability (Pain)” See Jamie Allen’s talk on the subject.
  • 38. 4 : ”Matrix of mutability (Pain)” See Jamie Allen’s talk on the subject.
  • 39. 4 : ”Matrix of mutability (Pain)”
  • 40. 5 : Blocking needs careful management
  • 41. 5 : Blocking needs careful management Blocking operations are really bad. Actors are all about resource sharing, and if someone is “behaving badly” it hurts everyone. Here is an example how blocking can grind an app to a halt. Next we’ll see how to avoid that… even if we have to live with the blocking code.
  • 42. 5 : Blocking needs careful management In simple terms: Blocking is bad because instead of doing something else, we just wait and do nothing (wasting CPU time)…
  • 43. 5 : Blocking needs careful management
  • 44. 5 : Blocking needs careful management Having that said, it’s not a bad question. Let’s investigate.
  • 45. 5 : Blocking needs careful management // BAD! (due to the blocking in Future): implicit val defaultDispatcher = system.dispatcher val routes: Route = post { complete { Future { // uses defaultDispatcher Thread.sleep(5000) // will block on the default dispatcher, System.currentTimeMillis().toString // starving the routing infra } } }
  • 46. 5 : Blocking needs careful management // BAD! (due to the blocking in Future): implicit val defaultDispatcher = system.dispatcher val routes: Route = post { complete { Future { // uses defaultDispatcher Thread.sleep(5000) // will block on the default dispatcher, System.currentTimeMillis().toString // starving the routing infra } } }
  • 47. 5 : Blocking needs careful management // application.conf my-blocking-dispatcher { type = Dispatcher executor = “thread-pool-executor" thread-pool-executor { // in Akka previous to 2.4.2: core-pool-size-min = 16 core-pool-size-max = 16 max-pool-size-min = 16 max-pool-size-max = 16 // or in Akka 2.4.2+ fixed-pool-size = 16 } throughput = 100 }
  • 48. 5 : Blocking needs careful management // GOOD (due to the blocking on a dedicated dispatcher): implicit val blockingDispatcher = system.dispatchers.lookup("my-blocking-dispatcher") val routes: Route = post { complete { Future { // uses the good "blocking dispatcher" that we configured, // instead of the default dispatcher – the blocking is isolated. Thread.sleep(5000) System.currentTimeMillis().toString } } }
  • 49. 5 : Blocking needs careful management The “Never block!” mantra sounds cool, but actually what we mean by it is “blocking needs careful management”. We use the “bulkhead” pattern separate out potentially blocking behaviours to their independent dispatchers (and should always do so). http://stackoverflow.com/questions/34641861/akka-http-blocking-in-a-future-blocks-the-server/34645097#34645097
  • 50. 6 : Never Await, for/flatMap instead!
  • 51. 6 : Never Await, for/flatMap instead! // ... extends Actor { import context.dispatcher import scala.concurrent.duration._ import scala.concurrent.Await // bad sign! // BAD!!! val fThings: Future[Things] = computeThings() val t: Things = Await.result(fThings, atMost = 3.seconds) val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds)
  • 52. 6 : Never Await, for/flatMap instead! // ... extends Actor { import context.dispatcher import scala.concurrent.duration._ import scala.concurrent.Await // bad sign! // BAD!!! val fThings: Future[Things] = computeThings() val t: Things = Await.result(fThings, atMost = 3.seconds) val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds) // Good: val fThingsWithDetails = for { t <- computeThings() d <- moreDetailsFor(t) } yield t -> d fThingsWithDetails foreach { case (things, details) => // case (things: Things, details: Details) => println(s"$things with $details") }
  • 53. 6 : Never Await, for/flatMap instead! // ... extends Actor { import context.dispatcher import scala.concurrent.duration._ import scala.concurrent.Await // bad sign! // BAD!!! val fThings: Future[Things] = computeThings() val t: Things = Await.result(fThings, atMost = 3.seconds) val d: Details = Await.result(moreDetailsFor(t), atMost = 3.seconds) // Good: val fThingsWithDetails = for { t <- computeThings() d <- moreDetailsFor(t) } yield t -> d fThingsWithDetails foreach { case (things, details) => // case (things: Things, details: Details) => println(s"$things with $details") } // adding timeout: val timeoutFuture = akka.pattern.after(3.seconds, context.system.scheduler) { Future.failed(new TimeoutException("My timeout details...")) } Future.firstCompletedOf(fThingsWithDetails :: timeoutFuture :: Nil) foreach { case (things, details) => // case (things: Things, details: Details) => println(s"$things with $details") }
  • 54. 7 : Avoid Java Serialization
  • 55. 7 : Avoid Java Serialization Java Serialization is the default one in Akka, since it’s easy to get started with it – no configuration needed. If you need performance and are running on multiple nodes, you must change the serialization. Popular formats are ProtoBuf or Kryo. Kryo is easier, but harder to evolve schema with. ProtoBuf is harder to maintain but great schema evolution.
  • 56. 7 : Avoid Java Serialization Benchmarking serialization impact on “ping pong” case. (Two actors sending a message between them.) in-process messaging, super fast.
 no serialization overhead.
  • 57. 7 : Avoid Java Serialization more work => increased latency => decreased throughput. over-the-network messaging, slower due to network and serialization.
  • 58. 7 : Avoid Java Serialization Java Serialization is known to be: very slow & footprint heavy
  • 59. 7 : Avoid Java Serialization It is on by default in Akka… Why? a) zero setup => simple to “play around” b) historical reasons - hard to remove the default Since 2.4 a warning is logged:
 WARNING: Using the default Java serializer for class [{}] which is not recommended because of performance implications. Use another serializer or disable this warning using the setting 'akka.actor.warn-about-java-serializer-usage'
  • 60. 7 : Avoid Java Serialization sbt> jmh:run 
 -f 1 -tu us 
 -wi 20 -i 10 -jvm /home/ktoso/opt/jdk1.8.0_65/bin/java -jvmArgsAppend -XX:+PreserveFramePointer -bm avgt .*pingPong.* [info] # JMH 1.10.3 (released 184 days ago, please consider updating!) [info] # VM version: JDK 1.8.0_65, VM 25.65-b01 [info] # VM invoker: /home/ktoso/opt/jdk1.8.0_65/bin/java [info] # VM options: -XX:+PreserveFramePointer [info] # Warmup: 20 iterations, 5 s each [info] # Measurement: 10 iterations, 1 s each [info] # Timeout: 10 min per iteration [info] # Threads: 1 thread, will synchronize iterations [info] # Benchmark mode: Average time, time/op [info] # Benchmark: akka.actor.ForkJoinActorBenchmark.pingPong [info] # Parameters: (serializer = java) github.com/ktoso/sbt-jmh openjdk.java.net/projects/code-tools/jmh/
  • 61. 7 : Avoid Java Serialization [info] # Warmup Iteration 1: 35.717 us/op . . . [info] # Warmup Iteration 19: 25.164 us/op [info] # Warmup Iteration 20: 23.862 us/op [info] Iteration 1: 25.790 us/op . . . [info] Iteration 10: 26.168 us/op 
 [info] Result "pingPong": [info] 25.464 ±(99.9%) 1.175 us/op [Average] [info] (min, avg, max) = (24.383, 25.464, 26.888), stdev = 0.777 [info] CI (99.9%): [24.289, 26.639] (assumes normal distribution) [info] ForkJoinActorBenchmark.pingPong java avgt 10 25.464 ± 1.175 us/op [info] ForkJoinActorBenchmark.pingPong off avgt 10 0.967 ± 0.657 us/op github.com/ktoso/sbt-jmh openjdk.java.net/projects/code-tools/jmh/
  • 62. 7 : Avoid Java Serialization Good serializers include (but are not limited to): Kryo, Google Protocol Buffers, SBE,Thrift, JSON even (sic!) // dependencies "com.github.romix.akka" %% "akka-kryo-serialization" % "0.4.0" // application.conf extensions = [“com.romix.akka.serialization.kryo.KryoSerializationExtension$"] 
 serializers { 
 java = "akka.serialization.JavaSerializer" kryo = "com.romix.akka.serialization.kryo.KryoSerializer" 
 } akka.actor.serialization-bindings { “com.mycompany.Example”: kryo . . . } [info] ForkJoinActorBenchmark.pingPong java avgt 10 25.464 ± 1.175 us/op [info] ForkJoinActorBenchmark.pingPong kryo avgt 10 4.348 ± 4.346 us/op [info] ForkJoinActorBenchmark.pingPong off avgt 10 0.967 ± 0.657 us/op
  • 63. 7 : Avoid Java Serialization ----sr--model.Order----h#-----J--idL--customert--Lmodel/Customer;L--descriptiont--Ljava/lang/String;L--orderLinest--Ljava/util/List;L--totalCostt--Ljava/ math/BigDecimal;xp--------ppsr--java.util.ArrayListx-----a----I--sizexp----w-----sr--model.OrderLine--&-1-S----I--lineNumberL--costq-~--L--descriptionq- ~--L--ordert--Lmodel/Order;xp----sr--java.math.BigDecimalT--W--(O---I--scaleL--intValt--Ljava/math/BigInteger;xr--java.lang.Number-----------xp----sr-- java.math.BigInteger-----;-----I--bitCountI--bitLengthI--firstNonzeroByteNumI--lowestSetBitI--signum[--magnitudet--[Bxq-~----------------------ur--[B------ T----xp----xxpq-~--xq-~-- Java Serialization final case class Order(id: Long, description: String, totalCost: BigDecimal, orderLines: ArrayList[OrderLines], customer: Customer) <order id="0" totalCost="0"><orderLines lineNumber="1" cost="0"><order>0</order></orderLines></order>XML…! {"order":{"id":0,"totalCost":0,"orderLines":[{"lineNumber":1,"cost":0,"order":0}]}}JSON…! ------java-util-ArrayLis-----model-OrderLin----java-math-BigDecima---------model-Orde-----Kryo…! Excellent post by James Sutherland @ http://java-persistence-performance.blogspot.com/2013/08/optimizing-java-serialization-java-vs.html
  • 64. 7 : Avoid Java Serialization for Persistence!!! Java Serialization is a horrible idea if you’re going to store the messages for a long time. For example, with Akka Persistence we store events “forever”. Use a serialization format that can evolve over time in a compatible way. It can be JSON or ProtocolBuffers (or Thrift etc).
  • 65. 7.5 : Trust no-one, benchmark everything! Always measure and benchmark properly before judging performance of a tool / library. Benchmarking is often very hard, use the right tools: - JMH (for Scala via: ktoso/sbt-jmh) -YourKit / JProfiler / … - Linux perf_events 7.5
  • 66. 8 : Let it Crash! Supervision, Failures & Errors
  • 67. http://www.reactivemanifesto.org/ 8 : Let it Crash! Supervision, Failures & Errors Error … which is an expected and coded-for condition—for example an error discovered during input validation, that will be communicated to the client … Failure … is an unexpected event within a service that prevents it from continuing to function normally. 
 A failure will generally prevent responses to the current, and possibly all following, client requests.
  • 68. http://www.reactivemanifesto.org/ 8 : Let it Crash! Supervision, Failures &
  • 69. http://www.reactivemanifesto.org/ 8 : Let it Crash! Supervision, Failures & Errors
  • 70. http://www.reactivemanifesto.org/ 8 : Let it Crash! Supervision, Failures & Errors Error: “Not enough cash.”
  • 71. http://www.reactivemanifesto.org/ 8 : Let it Crash! Supervision, Failures & Errors Error: “Unable to fulfil request” Failure: “Row 3 is broken”
  • 72. 9 : Backoff Supervision
  • 73. 9 : Backoff Supervision
  • 74. 9 : Backoff Supervision
  • 75. 9 : Backoff Supervision
  • 76. 9 : Backoff Supervision Our goal is to “let things crash” and “recover gracefully” Not to hammer the DB while it tries to recover!
  • 77. 9 : Backoff Supervision
  • 78. 9 : Backoff Supervision
  • 79. 9 : Backoff Supervision IF we allowed immediate restarts… we could end up in “infinite replay+fail hell”. (we don’t. since Persistence went stable in 2.4.x)
  • 80. 9 : Backoff Supervision
  • 81. 9 : Backoff Supervision Many PersistentActors Fail and Stop.
  • 82. 9 : Backoff Supervision
  • 83. 9 : Backoff Supervision Backoff Supervisor counts failures and starts “the same” entity after exponential timeouts.
  • 84. 9 : Backoff Supervision
  • 85. 10 : Design using State Machines
  • 86. 10 : Design using State Machines def receive = { case Thingy() => // ... case AnotherThingy() => // ... case DoOtherThings() => // ... case PleaseGoAway() => // ... case CarryOn() => // ... case MakeSomething() => // ... // ... }
  • 87. 10 : Design using State Machines def receive = { case Thingy() => // ... case AnotherThingy() => // ... case DoOtherThings() => // ... case PleaseGoAway() => // ... case CarryOn() => // ... case MakeSomething() => // ... // ... } Good: Actors avoid the “pyramid of doom”. Pyramid of doom in some async programming styles.
  • 88. 10 : Design using State Machines def receive = { case Thingy() => // ... case AnotherThingy() => // ... case DoOtherThings() => // ... case PleaseGoAway() => // ... case CarryOn() => // ... case MakeSomething() => // ... // ... } That well works because “everything is a message”:
  • 89. 10 : Design using State Machines def receive = awaitingInstructions def awaitingInstructions: Receive = terminationHandling orElse { case CarryOn() => // ... case MakeSomething(metadata) => // ... context become makeThings(meta) } def makeThings(metadata: Metadata): Receive = terminationHandling orElse { case Thingy() => // make a thingy ... case AnotherThingy() => // make another thingy ... case DoOtherThings(meta) => // ... context become awaitingInstructions } def terminationHandling: Receive = { case PleaseGoAway() => // ... context stop self } DoOtherThings MakeSomething
  • 90. 10 : Design using State Machines We also provide an FSM (Finite State Machine) helper trait. You may enjoy it sometimes, give it a look. DoOtherThings MakeSomething http://doc.akka.io/docs/akka/2.4.1/scala/fsm.html class Buncher extends FSM[State, Data] { startWith(Idle, Uninitialized) when(Idle) { case Event(SetTarget(ref), Uninitialized) => stay using Todo(ref, Vector.empty) } // transition elided ... when(Active, stateTimeout = 1 second) { case Event(Flush | StateTimeout, t: Todo) => goto(Idle) using t.copy(queue = Vector.empty) } // unhandled elided ... initialize() }
  • 91. 11 : Cluster Convergence and Joining
  • 92. 11 : Cluster Convergence and Joining http://doc.akka.io/docs/akka/2.4.1/common/cluster.html Cluster Gossip Convergence When a node can prove that the cluster state it is observing has been observed by all other nodes in the cluster.
  • 93. 11 : Cluster Convergence and Joining http://doc.akka.io/docs/akka/2.4.1/common/cluster.html Cluster Gossip Convergence When a node can prove that the cluster state it is observing has been observed by all other nodes in the cluster. Convergence is required for “Leader actions”, which include Join-ing and Remove-ing a node. Down-ing can happen without convergence.
  • 94. 11 : Cluster Convergence and Joining http://doc.akka.io/docs/akka/2.4.1/common/cluster.html
  • 95. 11 : Cluster Convergence and Joining http://doc.akka.io/docs/akka/2.4.1/common/cluster.html akka.cluster.allow-weakly-up-members=on
  • 96. 11 : Cluster Convergence and Joining
  • 97. 11 : Cluster Convergence and Joining
  • 98. 11 : Cluster Convergence and Joining
  • 99. 11 : Cluster Convergence and Joining
  • 100. 11 : Cluster Convergence and Joining
  • 101. 11 : Cluster Convergence and Joining Everyone has ‘seen’ Kurt joining, move him to Up.
  • 102. 11 : Cluster Convergence and Joining Kurt is now with us in the Cluster.
  • 103. 11 : Cluster Convergence and Joining I can’t hear Kurt… He’s unreachable…
  • 104. 11 : Cluster Convergence and Joining Kurt does has not seen Rei… I can not mark him as Up! allow-weakly-up-members=off // default
  • 105. 11 : Cluster Convergence and Joining I’ll mark Rei as “WeaklyUp” until Kurt is back. allow-weakly-up-members=on allow-weakly-up-members
  • 106. 11 : Cluster Convergence and Joining Kurt is back! Once he has seen Rei I’ll mark Rei as Up. allow-weakly-up-members=on allow-weakly-up-members
  • 107. 12 : Cluster Partitions and “Down”
  • 108. 12 : Cluster Partitions and “Down”
  • 109. 12 : Cluster Partitions and “Down” I’m going home…
  • 110. 12 : Cluster Partitions and “Down” Make sure the others have heard you say goodbye before you leave. Vanishes immediately.
  • 111. 12 : Cluster Partitions and “Down” Make sure the others have heard you say goodbye before you leave. “Where’s Bill? I did not hear him say Goodbye!” “Failure Detector” used to determine UNREACHABLE.
  • 112. 12 : Cluster Partitions and “Down” Failure detection only triggers “UNREACHABLE”. Nodes can come back from that state.
  • 113. 12 : Cluster Partitions and “Down” Declaring DOWN is done by either timeouts (which is rather unsafe) [auto-downing]. Or by “voting” or “majority” among the members of the cluster [split-brain-resolver].
  • 114. 12 : Cluster Partitions and “Down”
  • 115. 12 : Cluster Partitions and “Down” お 前 は も う 死 ん で い る . . . . Node declared “DOWN” comes back…
  • 116. 12 : Cluster Partitions and “Down” You are already dead.
  • 117. 12 : Cluster Partitions and “Down”Why do we do that? In order to guarantee consistency via “single writer principle”. Note: Akka Distributed Data has no need for “single writer”, it’s CRDT based. But it’s harder to model things as CRDT, so it’s a trade off. You are already dead.
  • 118. 12 : Cluster Partitions and “Down” Notice that we do not mention “Quarantined”. That is a state in Akka Remoting, not Cluster. It’s a terminal state from which one can never recover. TL;DR; use Akka Cluster instead of Remoting. it’s pretty much always the thing you need (better than remoting).
  • 119. 13 : A fishing rod is a Tool. Akka is a Toolkit.
  • 120. 13 : A fishing rod is a Tool. Akka is a Toolkit. Akka strives is Toolkit, not a Framework. “Give a man a fish and you feed him for a day teach a man to fish and you feed him for a lifetime.”
  • 121. 13 : A fishing rod is a Tool. Akka is a Toolkit. Akka strives is Toolkit, not a Framework. Play is a Framework, Lagom is a Framework.
  • 122. 13 : Akka is a Toolkit, pick the right tools for the job. “Constraints Liberate, Liberties Constrain” Runar Bjarnason Runar’s excellent talk @ Scala.World 2015
  • 123. 13 : Akka is a Toolkit, pick the right tools for the job. Runar’s excellent talk @ Scala.World 2015 The less powerful abstraction must be built on top of more powerful abstractions.
  • 124. 13 : Akka is a Toolkit, pick the right tools for the job. Runar’s excellent talk @ Scala.World 2015 Asynchronous processing toolbox:
  • 125. 13 : Akka is a Toolkit, pick the right tools for the job. Runar’s excellent talk @ Scala.World 2015 Asynchronous processing toolbox:
  • 126. 13 : Akka is a Toolkit, pick the right tools for the job. Asynchronous processing toolbox:
  • 127. 13 : Akka is a Toolkit, pick the right tools for the job. Single value, no streaming by definition. Local abstraction.
 Execution contexts.
  • 128. 13 : Akka is a Toolkit, pick the right tools for the job. Mostly static processing layouts. Well typed and Back-pressured!
  • 129. 13 : Akka is a Toolkit, pick the right tools for the job. Plain Actor’s younger brother, experimental. Location transparent, well typed. Technically unconstrained in actions performed
  • 130. 13 : Akka is a Toolkit, pick the right tools for the job. Runar’s excellent talk @ Scala.World 2015 Location transparent. Various resilience mechanisms. (watching, persistent recovering, migration, pools) Untyped and unconstrained in actions performed.
  • 131. 13 : Picking the tools – distributing / sharding processing Runar’s excellent talk @ Scala.World 2015
  • 132. 13 : Picking the tools – distributing / sharding processing Runar’s excellent talk @ Scala.World 2015Whitepaper by Pat Helland, 2005
 http://cidrdb.org/cidr2005/papers/P12.pdf
  • 133. 13 : Picking the tools – “element by element” processing Runar’s excellent talk @ Scala.World 2015 // types: _ Source[Int, Unit] Flow[Int, String, Unit] Sink[String, Future[String]] Source.single(1).map(_.toString).runWith(Sink.head)
  • 134. 13 : Picking the tools – streaming HTTP APIs
  • 135. 13 : Picking the tools – streaming HTTP APIs
  • 136. 13 : Picking the tools – streaming HTTP APIs
  • 137. 13 : Picking the tools – streaming HTTP APIs
  • 138. No demand from TCP = No demand upstream = Source won’t generate tweets 13 : Picking the tools – streaming HTTP APIs
  • 139. No demand from TCP = No demand upstream = Source won’t generate tweets => 13 : Picking the tools – streaming HTTP APIs
  • 140. No demand from TCP = No demand upstream = Source won’t generate tweets => Bounded memory stream processing! 13 : Picking the tools – streaming HTTP APIs
  • 141. 14 : Happy hAkking, Community!
  • 142. 14 : Happy hAkking, Community! akka.io – website github.com/akka/akka/issues – help out! “community-contrib” or “small” for starters groups.google.com/group/akka-user – mailing list gitter.im/akka/akka – chat about using Akka gitter.im/akka/dev – chat about developing Akka
  • 143. Links • http://stackoverflow.com/questions/34641861/akka-http-blocking- in-a-future-blocks-the-server/34645097#34645097 • The wonderful Zen paintings to buy here:
 http://paintingwholesalechina.com/products/chinese-culture-zen- no-1-academic-chinese-painting • http://doc.akka.io/docs/akka/2.4.1/common/cluster.html • http://www.mit.edu/~xela/tao.html • http://doc.akka.io/docs/akka/2.4.1/common/cluster.html • http://doc.akka.io/docs/akka/2.4.1/scala/cluster-usage.html • akka.io et al.
  • 144. Thanks! ktoso @ typesafe.com twitter: ktosopl github: ktoso team blog: letitcrash.com home: akka.io Thus spake the Master Programmer: “After three days without programming, life becomes meaningless.”
  • 145. lightbend.com/contact Reactive Roundtable World Tour by Lightbend lightbend.com/reactive-roundtable PoV/Pilot Enablement
 Accelerate Project Success
  • 146. ©Typesafe 2016 – All Rights Reserved