0
Building 
Reactive Systems 
with Akka 
Jonas Bonér 
Typesafe 
CTO & co-founder 
Twitter: @jboner
The rules of the game 
have changed
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
3 
Apps in the 60s-90s 
were written for 
Apps today 
are written for 
Single machines Clusters of machines 
Single core p...
Cost Gravity is at Work 
X
Cost Gravity is at Work 
X
Reactive applications share four traits 
Reactive 
Applications 
5
Reactive applications enrich the user 
experience with low latency response.
Responsive 
• Real-time, engaging, rich and collaborative 
• Create an open and ongoing dialog with users 
• More efficien...
Reactive applications react to 
changes in the world around them.
Message-Driven 
• Loosely coupled architecture, easier to extend, maintain, evolve 
• Asynchronous and non-blocking 
• Con...
Introducing the Actor Model
11 
The Actor Model
11 
The Actor Model 
A computational model that embodies:
11 
The Actor Model 
A computational model that embodies: 
✓ Processing
11 
The Actor Model 
A computational model that embodies: 
✓ Processing 
✓ Storage
11 
The Actor Model 
A computational model that embodies: 
✓ Processing 
✓ Storage 
✓ Communication
A computational model that embodies: 
✓ Processing 
✓ Storage 
✓ Communication 
Supports 3 axioms—when an Actor receives a...
A computational model that embodies: 
✓ Processing 
✓ Storage 
✓ Communication 
Supports 3 axioms—when an Actor receives a...
A computational model that embodies: 
✓ Processing 
✓ Storage 
✓ Communication 
Supports 3 axioms—when an Actor receives a...
A computational model that embodies: 
✓ Processing 
✓ Storage 
✓ Communication 
Supports 3 axioms—when an Actor receives a...
The essence of an actor 
from Akka’s perspective 
0. DEFINE 
1. CREATE 
2. SEND 
3. BECOME 
4. SUPERVISE 
12
public class Greeting implements Serializable { 
public final String who; 
public Greeting(String who) { this.who = who; }...
public class Greeting implements Serializable { 
public final String who; 
public Greeting(String who) { this.who = who; }...
public class Greeting implements Serializable { 
public final String who; 
public Greeting(String who) { this.who = who; }...
public class Greeting implements Serializable { 
public final String who; 
public Greeting(String who) { this.who = who; }...
1. CREATE 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef greeter = 
system.actorOf(Props.create(Greete...
1. CREATE 
Create an Actor system 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef greeter = 
system.act...
1. CREATE 
Create an Actor system 
Actor configuration 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef ...
1. CREATE 
Create an Actor system 
Actor configuration 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef ...
1. CREATE 
Create an Actor system 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef greeter = 
system.act...
1. CREATE 
Create an Actor system 
ActorSystem system = ActorSystem.create("MySystem"); 
! 
ActorRef greeter = 
system.act...
0. DEFINE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
13...
0. DEFINE 
13 
Define the message(s) the Actor 
should be able to respond to 
case class Greeting(who: String) 
! 
class G...
0. DEFINE 
13 
Define the message(s) the Actor 
should be able to respond to 
Define the Actor class 
case class Greeting(...
0. DEFINE 
13 
Define the message(s) the Actor 
should be able to respond to 
Define the Actor class 
case class Greeting(...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
ca...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
Cr...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
Cr...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
ca...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
Cr...
1. CREATE 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
Cr...
Actors can form hierarchies 
Guardian System Actor
Actors can form hierarchies 
Guardian System Actor 
system.actorOf(Props.create(Foo.class), “Foo”);
Actors can form hierarchies 
Foo 
Guardian System Actor 
system.actorOf(Props.create(Foo.class), “Foo”);
Actors can form hierarchies 
Foo 
Guardian System Actor 
context().actorOf(Props.create(A.class), “A”);
Actors can form hierarchies 
A 
Foo 
Guardian System Actor 
context().actorOf(Props.create(A.class), “A”);
Actors can form hierarchies 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
Guardian System Actor
Actors can form hierarchies 
Guardian System Actor
Actors can form hierarchies 
Guardian System Actor 
system.actorOf(Props[Foo], “Foo”)
Actors can form hierarchies 
Foo 
Guardian System Actor 
system.actorOf(Props[Foo], “Foo”)
Actors can form hierarchies 
Foo 
Guardian System Actor 
context.actorOf(Props[A], “A”)
Actors can form hierarchies 
A 
Foo 
Guardian System Actor 
context.actorOf(Props[A], “A”)
Actors can form hierarchies 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
Guardian System Actor
Name resolution—like a file-system 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
Guardian System Actor
Name resolution—like a file-system 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
/Foo 
Guardian System Actor
Name resolution—like a file-system 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
/Foo 
/Foo/A 
Guardian System Actor
Name resolution—like a file-system 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
/Foo 
/Foo/A 
/Foo/A/B 
Guardian System Actor
Name resolution—like a file-system 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
/Foo 
/Foo/A 
/Foo/A/B 
/Foo/A/D 
Guardian System Act...
2. SEND 
X 
greeter.tell(new Greeting("Charlie Parker”), sender);
2. SEND 
X 
greeter.tell(new Greeting("Charlie Parker”), sender); 
Send the message asynchronously
2. SEND 
X 
Pass in the sender ActorRef 
greeter.tell(new Greeting("Charlie Parker”), sender); 
Send the message asynchron...
Bring it together 
X 
public class Greeting implements Serializable { 
public final String who; 
public Greeting(String wh...
2. SEND 
17 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
...
2. SEND 
17 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def receive = { 
...
Bring it together 
18 
case class Greeting(who: String) 
! 
class GreetingActor extends Actor with ActorLogging { 
def rec...
DEMO TIME A simple game of ping pong
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
X 
public class Greeter extends AbstractActor { 
public Greeter { 
receive(ReceiveBuilder. 
match(Greeting.clas...
3. BECOME 
19 
class GreetingActor extends Actor with ActorLogging { 
def receive = happy 
! 
val happy: Receive = { 
case...
3. BECOME 
19 
class GreetingActor extends Actor with ActorLogging { 
def receive = happy 
! 
val happy: Receive = { 
case...
Reactive applications are architected 
to handle failure at all levels.
Resilient 
• Failure is embraced as a natural state in the app lifecycle 
• Resilience is a first-class construct 
• Failu...
Think Vending Machine
Think Vending Machine 
Coffee 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Add more coins 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Add more coins 
Programmer Machine 
Gets coffee
Think Vending Machine 
Coffee 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Out of coffee beans error 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
OutW of corfofeen begans error 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Programmer Machine
Think Vending Machine 
Coffee 
Inserts coins 
Out of 
coffee beans 
error 
Programmer Machine
Think Vending Machine 
Service 
Guy 
Coffee 
Inserts coins 
Out of 
coffee beans 
error 
Programmer Machine
Think Vending Machine 
Service 
Guy 
Coffee 
Inserts coins 
Out of 
coffee beans 
error 
Programmer Machine 
Adds 
more 
b...
Think Vending Machine 
Service 
Guy 
Coffee 
Inserts coins 
Programmer Machine 
Gets coffee 
Out of 
coffee beans 
error 
...
The Right Way 
Client Service
The Right Way 
Request 
Client Service
The Right Way 
Request 
Client Service 
Response
The Right Way 
Request 
Validation Error 
Client Service 
Response
The Right Way 
Request 
Validation Error 
Client Service 
Response 
Application 
Error
The Right Way 
Supervisor 
Request 
Validation Error 
Client Service 
Response 
Application 
Error
The Right Way 
Supervisor 
Request 
Validation Error 
Client Service 
Response 
Application 
Error 
Manages 
Failure
Use Bulkheads 
• Isolate the failure 
• Compartmentalize 
• Manage failure locally 
• Avoid cascading failures
Use Bulkheads 
• Isolate the failure 
• Compartmentalize 
• Manage failure locally 
• Avoid cascading failures
Enter Supervision
Enter Supervision
Supervisor hierarchies 
A 
Foo Bar 
B 
C 
B 
E 
A 
D 
C 
Automatic and mandatory supervision
4. SUPERVISE 
X 
Every single actor has a default supervisor strategy. 
Which is usually sufficient. 
But it can be overri...
4. SUPERVISE 
X 
class Supervisor extends UntypedActor { 
private SupervisorStrategy strategy = new OneForOneStrategy( 
10...
Monitor through Death Watch 
X 
public class WatchActor extends AbstractActor { 
final ActorRef child = context().actorOf(...
Monitor through Death Watch 
X 
public class WatchActor extends AbstractActor { 
final ActorRef child = context().actorOf(...
Monitor through Death Watch 
X 
public class WatchActor extends AbstractActor { 
final ActorRef child = context().actorOf(...
Monitor through Death Watch 
X 
public class WatchActor extends AbstractActor { 
final ActorRef child = context().actorOf(...
4. SUPERVISE 
29 
Every single actor has a default 
supervisor strategy. 
Which is usually sufficient. 
But it can be over...
4. SUPERVISE 
29 
Every single actor has a default 
supervisor strategy. 
Which is usually sufficient. 
But it can be over...
4. SUPERVISE 
29 
class Supervisor extends Actor { 
override val supervisorStrategy = 
OneForOneStrategy(maxNrOfRetries = ...
Cleanup & (Re)initialization 
30 
class Worker extends Actor { 
... 
override def preRestart( 
reason: Throwable, message:...
Monitor through Death Watch 
31 
class Watcher extends Actor { 
val child = context.actorOf(Props.empty, "child") 
context...
Monitor through Death Watch 
31 
Create a child actor 
class Watcher extends Actor { 
val child = context.actorOf(Props.em...
Monitor through Death Watch 
31 
Create a child actor 
Watch it 
class Watcher extends Actor { 
val child = context.actorO...
Monitor through Death Watch 
31 
Create a child actor 
Watch it 
class Watcher extends Actor { 
val child = context.actorO...
Reactive applications scale up 
and down to meet demand.
Elastic 
• Elasticity and Scalability to embrace the Cloud 
• Adaptive Scale on Demand 
• Clustered servers support joinin...
34 
Scale UP 
Scale OUT
34 
Essentially the same thing
35 
We need to 
1. Minimize Contention 
2. Maximize Locality of Reference
36 
Share 
NOTHING 
Design
Fully event-driven apps are a necessity 
X 
Amdahl’s Law will hunt you down
Define a router 
ActorRef router = context().actorOf( 
new RoundRobinPool(5).props(Props.create(Worker.class)), 
“router”)...
Define a router 
37 
val router = context.actorOf( 
RoundRobinPool(5).props(Props[Worker])), “router”)
…or from config 
38 
akka.actor.deployment { 
/service/router { 
router = round-robin-pool 
resizer { 
lower-bound = 12 
u...
Turn on clustering 
39 
akka { 
actor { 
provider = "akka.cluster.ClusterActorRefProvider" 
... 
} 
cluster { 
seed-nodes ...
Use clustered routers 
40 
akka.actor.deployment 
{ 
/service/master 
{ 
router 
= 
consistent-­‐hashing-­‐pool 
nr-­‐of-­...
Use clustered routers 
40 
Or perhaps use an 
AdaptiveLoadBalancingPool 
akka.actor.deployment 
{ 
/service/master 
{ 
rou...
Use clustered pub-sub 
41
Use clustered pub-sub 
41 
class Subscriber extends Actor { 
val mediator = 
DistributedPubSubExtension(context.system).me...
Use clustered pub-sub 
41 
class Publisher extends Actor { 
val mediator = 
DistributedPubSubExtension(context.system).med...
• Cluster Membership 
• Cluster Pub/Sub 
• Cluster Leader 
• Clustered Singleton 
• Cluster Roles 
• Cluster Sharding 
42 ...
• Supports two different models: 
• Command Sourcing 
• Event Sourcing 
• Great for implementing 
• durable actors 
• repl...
X 
Command Sourcing Event Sourcing
X 
Command Sourcing Event Sourcing 
write-ahead-log
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
X 
Command Sourcing Event Sourcing 
write-ahead-log derive events from a command 
same behavior during recovery 
as normal...
Domain Events 
• Things that have completed, facts 
• Immutable 
• Verbs in past tense 
Akka 
Persistence 
Webinar 
• Cust...
Life beyond Distributed Transactions: 
an Apostate’s Opinion 
Position Paper by Pat Helland 
http://www-­‐db.cs.wisc.edu/c...
Consistency boundary 
• An Actor is can define an Aggregate Root 
• Each containing one or more Entities 
• Aggregate Root...
DEMO TIME Persist a game of ping pong
http://reactivemanifesto.org
Typesafe Activator 
http://typesafe.com/platform/getstarted
• Purely asynchronous and non-blocking 
web frameworks 
• No container required, no inherent 
bottlenecks in session manag...
Reactive is being adopted across 
a wide range of industries.
50 
Finance Internet/Social Media Mfg/Hardware Government Retail
Questions?
©Typesafe 2014 – All Rights Reserved
Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)
Building Reactive Systems with Akka (in Java 8 or Scala)
Upcoming SlideShare
Loading in...5
×

Building Reactive Systems with Akka (in Java 8 or Scala)

16,107

Published on

Learn how to build Reactive Systems with Akka. Examples in both Java 8 and Scala.

Abstract:
The demands and expectations for applications have changed dramatically in recent years. Applications today are deployed on a wide range of infrastructure; from mobile devices up to thousands of nodes running in the cloud—all powered by multi-core processors. They need to be rich and collaborative, have a real-time feel with millisecond response time and should never stop running. Additionally, modern applications are a mashup of external services that need to be consumed and composed to provide the features at hand. We are seeing a new type of applications emerging to address these new challenges—these are being called Reactive Applications.

In this talk we will introduce you to Akka and discuss how it can help you deliver on the four key traits of Reactive; Responsive, Resilient, Elastic and Message-Driven. We will start with the basics of Akka and work our way towards some of its more advanced modules such as Akka Cluster and Akka Persistence—all driven through code and practical examples.

Transcript of "Building Reactive Systems with Akka (in Java 8 or Scala)"

  1. 1. Building Reactive Systems with Akka Jonas Bonér Typesafe CTO & co-founder Twitter: @jboner
  2. 2. The rules of the game have changed
  3. 3. 3 Apps in the 60s-90s were written for Apps today are written for
  4. 4. 3 Apps in the 60s-90s were written for Apps today are written for Single machines
  5. 5. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines
  6. 6. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors
  7. 7. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors
  8. 8. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM
  9. 9. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM
  10. 10. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk
  11. 11. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk
  12. 12. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks
  13. 13. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks
  14. 14. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users
  15. 15. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users Lots of concurrent users
  16. 16. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users Lots of concurrent users Small data sets
  17. 17. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users Lots of concurrent users Small data sets Large data sets
  18. 18. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users Lots of concurrent users Small data sets Large data sets Latency in seconds
  19. 19. 3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors Expensive RAM Cheap RAM Expensive disk Cheap disk Slow networks Fast networks Few concurrent users Lots of concurrent users Small data sets Large data sets Latency in seconds Latency in milliseconds
  20. 20. Cost Gravity is at Work X
  21. 21. Cost Gravity is at Work X
  22. 22. Reactive applications share four traits Reactive Applications 5
  23. 23. Reactive applications enrich the user experience with low latency response.
  24. 24. Responsive • Real-time, engaging, rich and collaborative • Create an open and ongoing dialog with users • More efficient workflow; inspires a feeling of connectedness • Fully Reactive enabling push instead of pull 7 “The move to these technologies is already paying off. Response times are down for processor intensive code–such as image and PDF generation–by around 75%.” Brian Pugh, VP of Engineering, Lucid Software
  25. 25. Reactive applications react to changes in the world around them.
  26. 26. Message-Driven • Loosely coupled architecture, easier to extend, maintain, evolve • Asynchronous and non-blocking • Concurrent by design, immutable state • Lower latency and higher throughput 9 “Clearly, the goal is to do these operations concurrently and non-blocking, so that entire blocks of seats or sections are not locked. We’re able to find and allocate seats under load in less than 20ms without trying very hard to achieve it.” Andrew Headrick, Platform Architect, Ticketfly
  27. 27. Introducing the Actor Model
  28. 28. 11 The Actor Model
  29. 29. 11 The Actor Model A computational model that embodies:
  30. 30. 11 The Actor Model A computational model that embodies: ✓ Processing
  31. 31. 11 The Actor Model A computational model that embodies: ✓ Processing ✓ Storage
  32. 32. 11 The Actor Model A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication
  33. 33. A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: 11 The Actor Model
  34. 34. A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: 1. Create new Actors 11 The Actor Model
  35. 35. A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: 1. Create new Actors 2. Send messages to Actors it knows 11 The Actor Model
  36. 36. A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: 1. Create new Actors 2. Send messages to Actors it knows 3. Designate how it should handle the next message it receives 11 The Actor Model
  37. 37. The essence of an actor from Akka’s perspective 0. DEFINE 1. CREATE 2. SEND 3. BECOME 4. SUPERVISE 12
  38. 38. public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; } } ! public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }} 0. DEFINE X
  39. 39. public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; } } ! public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }} 0. DEFINE X Define the message(s) the Actor should be able to respond to
  40. 40. public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; } } ! public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }} 0. DEFINE X Define the message(s) the Actor should be able to respond to Define the Actor class
  41. 41. public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; } } ! public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); }} 0. DEFINE X Define the message(s) the Actor should be able to respond to Define the Actor class Define the Actor’s behavior
  42. 42. 1. CREATE ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");
  43. 43. 1. CREATE Create an Actor system ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");
  44. 44. 1. CREATE Create an Actor system Actor configuration ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter");
  45. 45. 1. CREATE Create an Actor system Actor configuration ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name
  46. 46. 1. CREATE Create an Actor system ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name Create the Actor Actor configuration
  47. 47. 1. CREATE Create an Actor system ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name You get an ActorRef back Create the Actor Actor configuration
  48. 48. 0. DEFINE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { 13 case Greeting(who) => log.info(s"Hello ${who}") } }
  49. 49. 0. DEFINE 13 Define the message(s) the Actor should be able to respond to case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }
  50. 50. 0. DEFINE 13 Define the message(s) the Actor should be able to respond to Define the Actor class case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }
  51. 51. 0. DEFINE 13 Define the message(s) the Actor should be able to respond to Define the Actor class case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } } Define the Actor’s behavior
  52. 52. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")
  53. 53. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { Create an Actor system case Greeting(who) => log.info("Hello " + who) } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")
  54. 54. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { Create an Actor system case Greeting(who) => log.info("Hello " } Actor configuration + who) } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter")
  55. 55. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") Give it a name Create an Actor system Actor configuration
  56. 56. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { Create an Actor system case Greeting(who) => log.info("Hello " } Actor configuration + who) } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") Give it a name Create the Actor
  57. 57. 1. CREATE case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { Create an Actor system case Greeting(who) => log.info("Hello " } Actor configuration + who) } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") Give it a name You get an ActorRef bCarcekate the Actor
  58. 58. Actors can form hierarchies Guardian System Actor
  59. 59. Actors can form hierarchies Guardian System Actor system.actorOf(Props.create(Foo.class), “Foo”);
  60. 60. Actors can form hierarchies Foo Guardian System Actor system.actorOf(Props.create(Foo.class), “Foo”);
  61. 61. Actors can form hierarchies Foo Guardian System Actor context().actorOf(Props.create(A.class), “A”);
  62. 62. Actors can form hierarchies A Foo Guardian System Actor context().actorOf(Props.create(A.class), “A”);
  63. 63. Actors can form hierarchies A Foo Bar B C B E A D C Guardian System Actor
  64. 64. Actors can form hierarchies Guardian System Actor
  65. 65. Actors can form hierarchies Guardian System Actor system.actorOf(Props[Foo], “Foo”)
  66. 66. Actors can form hierarchies Foo Guardian System Actor system.actorOf(Props[Foo], “Foo”)
  67. 67. Actors can form hierarchies Foo Guardian System Actor context.actorOf(Props[A], “A”)
  68. 68. Actors can form hierarchies A Foo Guardian System Actor context.actorOf(Props[A], “A”)
  69. 69. Actors can form hierarchies A Foo Bar B C B E A D C Guardian System Actor
  70. 70. Name resolution—like a file-system A Foo Bar B C B E A D C Guardian System Actor
  71. 71. Name resolution—like a file-system A Foo Bar B C B E A D C /Foo Guardian System Actor
  72. 72. Name resolution—like a file-system A Foo Bar B C B E A D C /Foo /Foo/A Guardian System Actor
  73. 73. Name resolution—like a file-system A Foo Bar B C B E A D C /Foo /Foo/A /Foo/A/B Guardian System Actor
  74. 74. Name resolution—like a file-system A Foo Bar B C B E A D C /Foo /Foo/A /Foo/A/B /Foo/A/D Guardian System Actor
  75. 75. 2. SEND X greeter.tell(new Greeting("Charlie Parker”), sender);
  76. 76. 2. SEND X greeter.tell(new Greeting("Charlie Parker”), sender); Send the message asynchronously
  77. 77. 2. SEND X Pass in the sender ActorRef greeter.tell(new Greeting("Charlie Parker”), sender); Send the message asynchronously
  78. 78. Bring it together X public class Greeting implements Serializable { public final String who; public Greeting(String who) { this.who = who; } } public class Greeter extends AbstractActor {{ receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchAny(unknown -> { println(“Unknown message " + unknown); }).build()); } }} ! ActorSystem system = ActorSystem.create("MySystem"); ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); greeter.tell(new Greeting(“Charlie Parker”));
  79. 79. 2. SEND 17 case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker")
  80. 80. 2. SEND 17 case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker") Send the message asynchronously
  81. 81. Bring it together 18 case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s”Hello ${who}") } } ! val system = ActorSystem("MySystem") val greeter = system.actorOf(Props[GreetingActor], name = "greeter") greeter ! Greeting("Charlie Parker")
  82. 82. DEMO TIME A simple game of ping pong
  83. 83. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } }
  84. 84. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } context().become(ReceiveBuilder.
  85. 85. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } Change the behavior context().become(ReceiveBuilder.
  86. 86. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } Change the behavior context().become(ReceiveBuilder. match(Greeting.class, m -> {
  87. 87. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } Change the behavior context().become(ReceiveBuilder. match(Greeting.class, m -> { println(“Go Away!”);
  88. 88. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } Change the behavior context().become(ReceiveBuilder. match(Greeting.class, m -> { println(“Go Away!”); }).build());
  89. 89. 3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { !!!! }).build(); } } Change the behavior context().become(ReceiveBuilder. match(Greeting.class, m -> { println(“Go Away!”); }).build());
  90. 90. 3. BECOME 19 class GreetingActor extends Actor with ActorLogging { def receive = happy ! val happy: Receive = { case Greeting(who) => log.info(s”Hello ${who}") case Angry => context become angry } ! val angry: Receive = { case Greeting(_) => log.info("Go away!") case Happy => context become happy } }
  91. 91. 3. BECOME 19 class GreetingActor extends Actor with ActorLogging { def receive = happy ! val happy: Receive = { case Greeting(who) => log.info(s”Hello ${who}") case Angry => context become angry } ! val angry: Receive = { case Greeting(_) => log.info("Go away!") case Happy => context become happy } } Redefine the behavior
  92. 92. Reactive applications are architected to handle failure at all levels.
  93. 93. Resilient • Failure is embraced as a natural state in the app lifecycle • Resilience is a first-class construct • Failure is detected, isolated, and managed • Applications self heal 21 “The Typesafe Reactive Platform helps us maintain a very aggressive development and deployment cycle, all in a fail-forward manner. It’s now the default choice for developing all new services.” Peter Hausel, VP Engineering, Gawker Media
  94. 94. Think Vending Machine
  95. 95. Think Vending Machine Coffee Programmer Machine
  96. 96. Think Vending Machine Coffee Inserts coins Programmer Machine
  97. 97. Think Vending Machine Coffee Inserts coins Add more coins Programmer Machine
  98. 98. Think Vending Machine Coffee Inserts coins Add more coins Programmer Machine Gets coffee
  99. 99. Think Vending Machine Coffee Programmer Machine
  100. 100. Think Vending Machine Coffee Inserts coins Programmer Machine
  101. 101. Think Vending Machine Coffee Inserts coins Out of coffee beans error Programmer Machine
  102. 102. Think Vending Machine Coffee Inserts coins OutW of corfofeen begans error Programmer Machine
  103. 103. Think Vending Machine Coffee Inserts coins Programmer Machine
  104. 104. Think Vending Machine Coffee Inserts coins Out of coffee beans error Programmer Machine
  105. 105. Think Vending Machine Service Guy Coffee Inserts coins Out of coffee beans error Programmer Machine
  106. 106. Think Vending Machine Service Guy Coffee Inserts coins Out of coffee beans error Programmer Machine Adds more beans
  107. 107. Think Vending Machine Service Guy Coffee Inserts coins Programmer Machine Gets coffee Out of coffee beans error Adds more beans
  108. 108. The Right Way Client Service
  109. 109. The Right Way Request Client Service
  110. 110. The Right Way Request Client Service Response
  111. 111. The Right Way Request Validation Error Client Service Response
  112. 112. The Right Way Request Validation Error Client Service Response Application Error
  113. 113. The Right Way Supervisor Request Validation Error Client Service Response Application Error
  114. 114. The Right Way Supervisor Request Validation Error Client Service Response Application Error Manages Failure
  115. 115. Use Bulkheads • Isolate the failure • Compartmentalize • Manage failure locally • Avoid cascading failures
  116. 116. Use Bulkheads • Isolate the failure • Compartmentalize • Manage failure locally • Avoid cascading failures
  117. 117. Enter Supervision
  118. 118. Enter Supervision
  119. 119. Supervisor hierarchies A Foo Bar B C B E A D C Automatic and mandatory supervision
  120. 120. 4. SUPERVISE X Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden. class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.create(1, TimeUnit.MINUTES), DeciderBuilder. match(ArithmeticException.class, e -> resume()). match(NullPointerException.class, e -> restart()). matchAny( e -> escalate()). build()); ! @Override public SupervisorStrategy supervisorStrategy() { return strategy; }
  121. 121. 4. SUPERVISE X class Supervisor extends UntypedActor { private SupervisorStrategy strategy = new OneForOneStrategy( 10, Duration.create(1, TimeUnit.MINUTES), DeciderBuilder. match(ArithmeticException.class, e -> resume()). match(NullPointerException.class, e -> restart()). matchAny( e -> escalate()). build()); ! @Override public SupervisorStrategy supervisorStrategy() { return strategy; } ActorRef worker = context.actorOf( Props.create(Worker.class), "worker"); public void onReceive(Object i) throws Exception { … } }
  122. 122. Monitor through Death Watch X public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } }
  123. 123. Monitor through Death Watch X public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } } Create a child actor
  124. 124. Monitor through Death Watch X public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } } Create a child actor Watch it
  125. 125. Monitor through Death Watch X public class WatchActor extends AbstractActor { final ActorRef child = context().actorOf(Props.empty(), "child"); ! public WatchActor() { context().watch(child); receive(ReceiveBuilder. match(Terminated.class, t -> t.actor().equals(child), t -> { … // handle termination }).build() ); } } Create a child actor Watch it Handle termination message
  126. 126. 4. SUPERVISE 29 Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.
  127. 127. 4. SUPERVISE 29 Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden. class Supervisor extends Actor { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: Exception => Escalate } ! val worker = context.actorOf(Props[Worker], name = "worker") ! def receive = {
  128. 128. 4. SUPERVISE 29 class Supervisor extends Actor { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: Exception => Escalate } ! val worker = context.actorOf(Props[Worker], name = "worker") ! def receive = { case n: Int => worker forward n } } !
  129. 129. Cleanup & (Re)initialization 30 class Worker extends Actor { ... override def preRestart( reason: Throwable, message: Option[Any]) { ... // clean up before restart } override def postRestart(reason: Throwable) { ... // init after restart } }
  130. 130. Monitor through Death Watch 31 class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }
  131. 131. Monitor through Death Watch 31 Create a child actor class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }
  132. 132. Monitor through Death Watch 31 Create a child actor Watch it class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) ! def receive = { case Terminated(`child`) => … // handle child termination } }
  133. 133. Monitor through Death Watch 31 Create a child actor Watch it class Watcher extends Actor { val child = context.actorOf(Props.empty, "child") context.watch(child) Handle termination message ! def receive = { case Terminated(`child`) => … // handle child termination } }
  134. 134. Reactive applications scale up and down to meet demand.
  135. 135. Elastic • Elasticity and Scalability to embrace the Cloud • Adaptive Scale on Demand • Clustered servers support joining and leaving of nodes • More cost-efficient utilization of hardware 33 “Our traffic can increase by as much as 100x for 15 minutes each day. Until a couple of years ago, noon was a stressful time. Nowadays, it’s usually a non-event.” Eric Bowman, VP Architecture, Gilt Groupe
  136. 136. 34 Scale UP Scale OUT
  137. 137. 34 Essentially the same thing
  138. 138. 35 We need to 1. Minimize Contention 2. Maximize Locality of Reference
  139. 139. 36 Share NOTHING Design
  140. 140. Fully event-driven apps are a necessity X Amdahl’s Law will hunt you down
  141. 141. Define a router ActorRef router = context().actorOf( new RoundRobinPool(5).props(Props.create(Worker.class)), “router”) X
  142. 142. Define a router 37 val router = context.actorOf( RoundRobinPool(5).props(Props[Worker])), “router”)
  143. 143. …or from config 38 akka.actor.deployment { /service/router { router = round-robin-pool resizer { lower-bound = 12 upper-bound = 15 } } }
  144. 144. Turn on clustering 39 akka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... } cluster { seed-nodes = [ “akka.tcp://ClusterSystem@127.0.0.1:2551", “akka.tcp://ClusterSystem@127.0.0.1:2552" ] auto-down = off } }
  145. 145. Use clustered routers 40 akka.actor.deployment { /service/master { router = consistent-­‐hashing-­‐pool nr-­‐of-­‐instances = 100 ! cluster { enabled = on max-nr-of-instances-per-node = 3 allow-­‐local-­‐routees = on use-­‐role = compute } } }
  146. 146. Use clustered routers 40 Or perhaps use an AdaptiveLoadBalancingPool akka.actor.deployment { /service/master { router = consistent-­‐hashing-­‐pool nr-­‐of-­‐instances = 100 ! cluster { enabled = on max-nr-of-instances-per-node = 3 allow-­‐local-­‐routees = on use-­‐role = compute } } }
  147. 147. Use clustered pub-sub 41
  148. 148. Use clustered pub-sub 41 class Subscriber extends Actor { val mediator = DistributedPubSubExtension(context.system).mediator mediator ! Subscribe(“content”, self) def receive = { … } }
  149. 149. Use clustered pub-sub 41 class Publisher extends Actor { val mediator = DistributedPubSubExtension(context.system).mediator def receive = { case in: String => mediator ! Publish("content", in.toUpperCase) } }
  150. 150. • Cluster Membership • Cluster Pub/Sub • Cluster Leader • Clustered Singleton • Cluster Roles • Cluster Sharding 42 Other Akka Cluster features
  151. 151. • Supports two different models: • Command Sourcing • Event Sourcing • Great for implementing • durable actors • replication • CQRS etc. • Messages persisted to Journal and replayed on restart 43 Use Akka Persistence
  152. 152. X Command Sourcing Event Sourcing
  153. 153. X Command Sourcing Event Sourcing write-ahead-log
  154. 154. X Command Sourcing Event Sourcing write-ahead-log derive events from a command
  155. 155. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation
  156. 156. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery
  157. 157. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation
  158. 158. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation events cannot fail
  159. 159. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation events cannot fail allows retroactive changes to the business logic
  160. 160. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation events cannot fail allows retroactive changes to the business logic fixing the business logic will not affect persisted events
  161. 161. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation events cannot fail allows retroactive changes to the business logic fixing the business logic will not affect persisted events naming: represent intent, imperative
  162. 162. X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation only state-changing behavior during recovery persisted before validation events cannot fail allows retroactive changes to the business logic fixing the business logic will not affect persisted events naming: represent intent, imperative naming: things that have completed, verbs in past tense
  163. 163. Domain Events • Things that have completed, facts • Immutable • Verbs in past tense Akka Persistence Webinar • CustomerRelocated • CargoShipped • InvoiceSent “State transitions are an important part of our problem space and should be modeled within our domain.” Greg Young, 2008
  164. 164. Life beyond Distributed Transactions: an Apostate’s Opinion Position Paper by Pat Helland http://www-­‐db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf “In general, application developers simply do not implement large scalable applications assuming distributed transactions.” Pat Helland Akka Persistence Webinar
  165. 165. Consistency boundary • An Actor is can define an Aggregate Root • Each containing one or more Entities • Aggregate Root is the Transactional Boundary • Strong consistency within an Aggregate • Eventual consistency between Aggregates • No limit to scalability Akka Persistence Webinar
  166. 166. DEMO TIME Persist a game of ping pong
  167. 167. http://reactivemanifesto.org
  168. 168. Typesafe Activator http://typesafe.com/platform/getstarted
  169. 169. • Purely asynchronous and non-blocking web frameworks • No container required, no inherent bottlenecks in session management 48 Typesafe Reactive Platform • Actors are asynchronous and communicate via message passing • Supervision and clustering in support of fault tolerance • Asynchronous and immutable programming constructs • Composable abstractions enabling simpler concurrency and parallelism
  170. 170. Reactive is being adopted across a wide range of industries.
  171. 171. 50 Finance Internet/Social Media Mfg/Hardware Government Retail
  172. 172. Questions?
  173. 173. ©Typesafe 2014 – All Rights Reserved
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×