Slide 1

Slide 1 text

Building Reactive Systems with Akka Jonas Bonér Typesafe CTO & co-founder Twitter: @jboner

Slide 2

Slide 2 text

The rules of the game have changed

Slide 3

Slide 3 text

3 Apps in the 60s-90s were written for Apps today are written for

Slide 4

Slide 4 text

3 Apps in the 60s-90s were written for Apps today are written for Single machines

Slide 5

Slide 5 text

3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines

Slide 6

Slide 6 text

3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors

Slide 7

Slide 7 text

3 Apps in the 60s-90s were written for Apps today are written for Single machines Clusters of machines Single core processors Multicore processors

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Cost Gravity is at Work X

Slide 22

Slide 22 text

Cost Gravity is at Work X

Slide 23

Slide 23 text

Reactive  Applications Reactive applications share four traits 5

Slide 24

Slide 24 text

Reactive applications enrich the user experience with low latency response.

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Reactive applications react to 
 changes in the world around them.

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Introducing the Actor Model

Slide 29

Slide 29 text

11 The Actor Model

Slide 30

Slide 30 text

11 A computational model that embodies: The Actor Model

Slide 31

Slide 31 text

11 A computational model that embodies: ✓ Processing The Actor Model

Slide 32

Slide 32 text

11 A computational model that embodies: ✓ Processing ✓ Storage The Actor Model

Slide 33

Slide 33 text

11 A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication The Actor Model

Slide 34

Slide 34 text

11 A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: The Actor Model

Slide 35

Slide 35 text

11 A computational model that embodies: ✓ Processing ✓ Storage ✓ Communication Supports 3 axioms—when an Actor receives a message it can: 1. Create new Actors The Actor Model

Slide 36

Slide 36 text

11 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 The Actor Model

Slide 37

Slide 37 text

11 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 The Actor Model

Slide 38

Slide 38 text

The essence of an actor from Akka’s perspective 0. DEFINE 1. CREATE 2. SEND 3. BECOME 4. SUPERVISE 12

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); 1. CREATE

Slide 44

Slide 44 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); 1. CREATE Create an Actor system

Slide 45

Slide 45 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); 1. CREATE Create an Actor system Actor configuration

Slide 46

Slide 46 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name 1. CREATE Create an Actor system Actor configuration

Slide 47

Slide 47 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name 1. CREATE Create the Actor Create an Actor system Actor configuration

Slide 48

Slide 48 text

ActorSystem system = ActorSystem.create("MySystem"); ! ActorRef greeter = system.actorOf(Props.create(Greeter.class), “greeter"); Give it a name 1. CREATE Create the Actor You get an ActorRef back Create an Actor system Actor configuration

Slide 49

Slide 49 text

0. DEFINE 13 case class Greeting(who: String) ! class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info(s"Hello ${who}") } }

Slide 50

Slide 50 text

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}") } }

Slide 51

Slide 51 text

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}") } } Define the Actor class

Slide 52

Slide 52 text

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}") } } Define the Actor class Define the Actor’s behavior

Slide 53

Slide 53 text

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") 1. CREATE

Slide 54

Slide 54 text

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") 1. CREATE Create an Actor system

Slide 55

Slide 55 text

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") 1. CREATE Create an Actor system Actor configuration

Slide 56

Slide 56 text

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 1. CREATE Create an Actor system Actor configuration

Slide 57

Slide 57 text

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 1. CREATE Create the Actor Create an Actor system Actor configuration

Slide 58

Slide 58 text

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 1. CREATE Create the Actor You get an ActorRef back Create an Actor system Actor configuration

Slide 59

Slide 59 text

Guardian System Actor Actors can form hierarchies

Slide 60

Slide 60 text

Guardian System Actor system.actorOf(Props.create(Foo.class), “Foo”); Actors can form hierarchies

Slide 61

Slide 61 text

Foo Guardian System Actor system.actorOf(Props.create(Foo.class), “Foo”); Actors can form hierarchies

Slide 62

Slide 62 text

Foo Guardian System Actor context().actorOf(Props.create(A.class), “A”); Actors can form hierarchies

Slide 63

Slide 63 text

A Foo Guardian System Actor context().actorOf(Props.create(A.class), “A”); Actors can form hierarchies

Slide 64

Slide 64 text

A B Bar Foo C B E A D C Guardian System Actor Actors can form hierarchies

Slide 65

Slide 65 text

Guardian System Actor Actors can form hierarchies

Slide 66

Slide 66 text

Guardian System Actor system.actorOf(Props[Foo], “Foo”) Actors can form hierarchies

Slide 67

Slide 67 text

Foo Guardian System Actor system.actorOf(Props[Foo], “Foo”) Actors can form hierarchies

Slide 68

Slide 68 text

Foo Guardian System Actor context.actorOf(Props[A], “A”) Actors can form hierarchies

Slide 69

Slide 69 text

A Foo Guardian System Actor context.actorOf(Props[A], “A”) Actors can form hierarchies

Slide 70

Slide 70 text

A B Bar Foo C B E A D C Guardian System Actor Actors can form hierarchies

Slide 71

Slide 71 text

A B Bar Foo C B E A D C Guardian System Actor Name resolution—like a file-system

Slide 72

Slide 72 text

A B Bar Foo C B E A D C /Foo Guardian System Actor Name resolution—like a file-system

Slide 73

Slide 73 text

A B Bar Foo C B E A D C /Foo /Foo/A Guardian System Actor Name resolution—like a file-system

Slide 74

Slide 74 text

A B Bar Foo C B E A D C /Foo /Foo/A /Foo/A/B Guardian System Actor Name resolution—like a file-system

Slide 75

Slide 75 text

A B Bar Foo C B E A D C /Foo /Foo/A /Foo/A/B /Foo/A/D Guardian System Actor Name resolution—like a file-system

Slide 76

Slide 76 text

2. SEND X greeter.tell(new Greeting("Charlie Parker”), sender);

Slide 77

Slide 77 text

2. SEND X Send the message asynchronously greeter.tell(new Greeting("Charlie Parker”), sender);

Slide 78

Slide 78 text

2. SEND X Send the message asynchronously greeter.tell(new Greeting("Charlie Parker”), sender); Pass in the sender ActorRef

Slide 79

Slide 79 text

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”));

Slide 80

Slide 80 text

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")

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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")

Slide 83

Slide 83 text

DEMO TIME A simple game of ping pong

Slide 84

Slide 84 text

3. BECOME X public class Greeter extends AbstractActor { public Greeter { receive(ReceiveBuilder. match(Greeting.class, m -> { println(“Hello " + m.who); }). matchEquals(“stop" -> { ! ! ! ! }).build(); } }

Slide 85

Slide 85 text

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.

Slide 86

Slide 86 text

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.

Slide 87

Slide 87 text

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 -> {

Slide 88

Slide 88 text

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!”);

Slide 89

Slide 89 text

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());

Slide 90

Slide 90 text

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());

Slide 91

Slide 91 text

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 } }

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

Reactive applications are architected 
 to handle failure at all levels.

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

Think Vending Machine

Slide 96

Slide 96 text

Coffee Machine Programmer Think Vending Machine

Slide 97

Slide 97 text

Coffee Machine Programmer Inserts coins Think Vending Machine

Slide 98

Slide 98 text

Coffee Machine Programmer Inserts coins Add more coins Think Vending Machine

Slide 99

Slide 99 text

Coffee Machine Programmer Inserts coins Gets coffee Add more coins Think Vending Machine

Slide 100

Slide 100 text

Coffee Machine Programmer Think Vending Machine

Slide 101

Slide 101 text

Coffee Machine Programmer Inserts coins Think Vending Machine

Slide 102

Slide 102 text

Coffee Machine Programmer Inserts coins Think Vending Machine Out of coffee beans error

Slide 103

Slide 103 text

Coffee Machine Programmer Inserts coins Think Vending Machine Out of coffee beans error Wrong

Slide 104

Slide 104 text

Coffee Machine Programmer Inserts coins Think Vending Machine

Slide 105

Slide 105 text

Coffee Machine Programmer Inserts coins Out of coffee beans error Think Vending Machine

Slide 106

Slide 106 text

Coffee Machine Programmer Service Guy Inserts coins Out of coffee beans error Think Vending Machine

Slide 107

Slide 107 text

Coffee Machine Programmer Service Guy Inserts coins Out of coffee beans error Adds more beans Think Vending Machine

Slide 108

Slide 108 text

Coffee Machine Programmer Service Guy Inserts coins Gets coffee Out of coffee beans error Adds more beans Think Vending Machine

Slide 109

Slide 109 text

The Right Way Service Client

Slide 110

Slide 110 text

The Right Way Service Client Request

Slide 111

Slide 111 text

The Right Way Service Client Request Response

Slide 112

Slide 112 text

The Right Way Service Client Request Response Validation Error

Slide 113

Slide 113 text

The Right Way Service Client Request Response Validation Error Application Error

Slide 114

Slide 114 text

The Right Way Service Client Supervisor Request Response Validation Error Application Error

Slide 115

Slide 115 text

The Right Way Service Client Supervisor Request Response Validation Error Application Error Manages Failure

Slide 116

Slide 116 text

No content

Slide 117

Slide 117 text

• Isolate the failure • Compartmentalize • Manage failure locally • Avoid cascading failures Use Bulkheads

Slide 118

Slide 118 text

• Isolate the failure • Compartmentalize • Manage failure locally • Avoid cascading failures Use Bulkheads

Slide 119

Slide 119 text

Enter Supervision

Slide 120

Slide 120 text

Enter Supervision

Slide 121

Slide 121 text

A B Bar Foo C B E A D C Automatic and mandatory supervision Supervisor hierarchies

Slide 122

Slide 122 text

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; } Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.

Slide 123

Slide 123 text

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 { … } }

Slide 124

Slide 124 text

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() ); } }

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

4. SUPERVISE 29 Every single actor has a default supervisor strategy. Which is usually sufficient. But it can be overridden.

Slide 129

Slide 129 text

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") !

Slide 130

Slide 130 text

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 } } !

Slide 131

Slide 131 text

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 } }

Slide 132

Slide 132 text

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 } }

Slide 133

Slide 133 text

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 } } Create a child actor

Slide 134

Slide 134 text

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 } } Create a child actor Watch it

Slide 135

Slide 135 text

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 } } Create a child actor Watch it Handle termination message

Slide 136

Slide 136 text

Reactive applications scale up 
 and down to meet demand.

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

34 Scale OUT Scale UP

Slide 139

Slide 139 text

34 Essentially the same thing

Slide 140

Slide 140 text

35 1. Minimize Contention 2. Maximize Locality of Reference We need to

Slide 141

Slide 141 text

36 Share NOTHING Design

Slide 142

Slide 142 text

Fully event-driven apps are a necessity X Amdahl’s Law will hunt you down

Slide 143

Slide 143 text

Define a router X ActorRef router = context().actorOf( new RoundRobinPool(5).props(Props.create(Worker.class)), “router”)

Slide 144

Slide 144 text

Define a router 37 val router = context.actorOf( RoundRobinPool(5).props(Props[Worker])), “router”)

Slide 145

Slide 145 text

…or from config 38 akka.actor.deployment { /service/router { router = round-robin-pool resizer { lower-bound = 12 upper-bound = 15 } } }

Slide 146

Slide 146 text

Turn on clustering 39 akka { actor { provider = "akka.cluster.ClusterActorRefProvider" ... } cluster { seed-nodes = [ “akka.tcp://[email protected]:2551", “akka.tcp://[email protected]:2552" ] auto-down = off } }

Slide 147

Slide 147 text

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          }      }   }

Slide 148

Slide 148 text

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          }      }   } Or perhaps use an AdaptiveLoadBalancingPool

Slide 149

Slide 149 text

Use clustered pub-sub 41

Slide 150

Slide 150 text

Use clustered pub-sub 41 class Subscriber extends Actor { val mediator = DistributedPubSubExtension(context.system).mediator mediator ! Subscribe(“content”, self) def receive = { … } }

Slide 151

Slide 151 text

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) } }

Slide 152

Slide 152 text

• Cluster Membership • Cluster Pub/Sub • Cluster Leader • Clustered Singleton • Cluster Roles • Cluster Sharding 42 Other Akka Cluster features

Slide 153

Slide 153 text

• 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

Slide 154

Slide 154 text

X Command Sourcing Event Sourcing

Slide 155

Slide 155 text

X Command Sourcing Event Sourcing write-ahead-log

Slide 156

Slide 156 text

X Command Sourcing Event Sourcing write-ahead-log derive events from a command

Slide 157

Slide 157 text

X Command Sourcing Event Sourcing write-ahead-log derive events from a command same behavior during recovery as normal operation

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

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

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

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

Slide 163

Slide 163 text

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

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

Akka  Persistence  Webinar Domain Events • Things that have completed, facts • Immutable • Verbs in past tense • CustomerRelocated • CargoShipped • InvoiceSent “State transitions are an important part of our problem space and should be modeled within our domain.”   Greg Young, 2008

Slide 166

Slide 166 text

Akka  Persistence  Webinar Life beyond Distributed Transactions: an Apostate’s Opinion Position Paper by Pat Helland “In general, application developers simply do not implement large scalable applications assuming distributed transactions.”   Pat Helland http://www-­‐db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf

Slide 167

Slide 167 text

Akka  Persistence  Webinar 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

Slide 168

Slide 168 text

DEMO TIME Persist a game of ping pong

Slide 169

Slide 169 text

No content

Slide 170

Slide 170 text

http://reactivemanifesto.org

Slide 171

Slide 171 text

Typesafe Activator http://typesafe.com/platform/getstarted

Slide 172

Slide 172 text

48 Typesafe Reactive Platform • Actors are asynchronous and communicate via message passing • Supervision and clustering in support of fault tolerance • Purely asynchronous and non-blocking web frameworks • No container required, no inherent bottlenecks in session management • Asynchronous and immutable programming constructs • Composable abstractions enabling simpler concurrency and parallelism

Slide 173

Slide 173 text

Reactive is being adopted across
 a wide range of industries.

Slide 174

Slide 174 text

50 Finance Internet/Social Media Mfg/Hardware Government Retail

Slide 175

Slide 175 text

Questions?

Slide 176

Slide 176 text

©Typesafe 2014 – All Rights Reserved