Slide 1

Slide 1 text

Being Reactive is Good Kevin Webber, Developer Advocate, Typesafe

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Problem? » we used the right tools to build the wrong thing

Slide 12

Slide 12 text

Problem? » we used the right tools to build the wrong thing » proactive isn't always good

Slide 13

Slide 13 text

Problem? » we used the right tools to build the wrong thing » proactive isn't always good » reactive isn't always bad

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

» let principles guide our » design » tool selection » implementation choices

Slide 19

Slide 19 text

» let principles guide our » design » tool selection » implementation choices » principles should be accessible and universal

Slide 20

Slide 20 text

» let principles guide our » design » tool selection » implementation choices » principles should be accessible and universal » principles should help engineers » meet expectations » take advantage of the latest advancements in technology

Slide 21

Slide 21 text

What is Reactive?

Slide 22

Slide 22 text

asynchronous, non-blocking, real-time, highly- available, loosely coupled, scalable, fault-tolerant, concurrent, reactive, event-driven, push instead of pull, distributed, low latency, high throughput...

Slide 23

Slide 23 text

asynchronous, non-blocking, real-time, highly- available, loosely coupled, scalable, fault-tolerant, concurrent, reactive, event-driven, push instead of pull, distributed, low latency, high throughput... Too complicated. We need a simple vocabulary.

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Typesafe Reactive Platform » Play: RESTful API framework » Akka: Distributed computing framework » Spark: General purpose in- memory compute engine

Slide 29

Slide 29 text

Akka Users

Slide 30

Slide 30 text

Message-driven » distribution » location transparency » isolation

Slide 31

Slide 31 text

object GameEngineActor { def props = Props(new GameEngineActor) } }

Slide 32

Slide 32 text

object GameEngineActor { def props = Props(new GameEngineActor) } class GameEngineActor extends Actor { val log = Logging(context.system, this) var openGameQ = new Queue[ActorRef] }

Slide 33

Slide 33 text

object GameEngineActor { def props = Props(new GameEngineActor) } class GameEngineActor extends Actor { val log = Logging(context.system, this) var openGameQ = new Queue[ActorRef] def receive = { // find open game and register player for the game case r: RegisterPlayerRequest => findGame(r) ! r case _ => log.error(_) } }

Slide 34

Slide 34 text

object GameEngineActor { def props = Props(new GameEngineActor) } class GameEngineActor extends Actor { val log = Logging(context.system, this) var openGameQ = new Queue[ActorRef] def receive = { // find open game and register player for the game case r: RegisterPlayerRequest => findGame(r) ! r case _ => log.error(_) } private def findGame(r: RegisterPlayerRequest): ActorRef = { if (openGameQ.isEmpty) { // create a new game and add it to the queue val newGame = { val gameUuid = java.util.UUID.randomUUID.toString context.actorOf(Props[GameActor], name = "gameActor" + gameUuid) } openGameQ += newGame newGame } else { // pull a game off the queue that is waiting for players openGameQ.dequeue } } }

Slide 35

Slide 35 text

Resilient » supervision

Slide 36

Slide 36 text

Resilient » emitting errors

Slide 37

Slide 37 text

Resilient » handling errors

Slide 38

Slide 38 text

Resilient » dedicated separate error channel

Slide 39

Slide 39 text

Elastic » scale up » async » non-blocking

Slide 40

Slide 40 text

Elastic » scale up » async » non-blocking » scale out » immutable data » share nothing

Slide 41

Slide 41 text

Responsive » responsive to events » responsive to load » responsive to failure » responsive to users

Slide 42

Slide 42 text

» responsive a request for service is always answered, even when failures occur. » elastic services scale up and down on demand. » resilient services recover from failures. » message driven services respond to the world, not attempt to control what it does.

Slide 43

Slide 43 text

How can we envision Proactive Security Solutions as Reactive Security Solutions? Using: » Reactive principles » The Typesafe Reactive Platform

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

How do we get there? Applying the Reactive principles to build a fully reactive microservices system, using: » The Typesafe Reactive Platform » Third-party tools » Existing infrastructure (hybrid-cloud, etc)

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

Async in Action with the Play framework

Slide 48

Slide 48 text

Play Anatomy » Stateless: session is stored in the browser cookie » Actions: user-defined functions that run in a different context than the request loop

Slide 49

Slide 49 text

Play at its core » RESTful API framework

Slide 50

Slide 50 text

Play at its core » RESTful API framework » Familiar MVC paradigm

Slide 51

Slide 51 text

Play at its core » RESTful API framework » Familiar MVC paradigm » Embraces flows of data » WebSockets, SSE » File uploads

Slide 52

Slide 52 text

Play at its core » RESTful API framework » Familiar MVC paradigm » Embraces flows of data » WebSockets, SSE » File uploads » Integration with Akka » Distribute work via messaging

Slide 53

Slide 53 text

Single thread per request

Slide 54

Slide 54 text

Single thread per request » A thread keeps data in memory until it has access to the CPU

Slide 55

Slide 55 text

Single thread per request » A thread keeps data in memory until it has access to the CPU » More threads = more memory required

Slide 56

Slide 56 text

Single thread per request » A thread keeps data in memory until it has access to the CPU » More threads = more memory required » If a thread is idle while blocked (e.g, IO) » Memory is being consumed inefficiently » Must limit total number of threads » This can leave the CPU idle (bounded on memory)

Slide 57

Slide 57 text

Work stealing

Slide 58

Slide 58 text

» Play uses a fork join execution context with work stealing » Does not bind a thread to a request

Slide 59

Slide 59 text

» Play uses a fork join execution context with work stealing » Does not bind a thread to a request » Uses Futures and Thread Pools to let CPU go at full throttle

Slide 60

Slide 60 text

» Play uses a fork join execution context with work stealing » Does not bind a thread to a request » Uses Futures and Thread Pools to let CPU go at full throttle » Uses NIO.2 through Netty to avoid blocking on network IO

Slide 61

Slide 61 text

» Play uses a fork join execution context with work stealing » Does not bind a thread to a request » Uses Futures and Thread Pools to let CPU go at full throttle » Uses NIO.2 through Netty to avoid blocking on network IO » Stateless (no HTTP session)

Slide 62

Slide 62 text

» Play uses a fork join execution context with work stealing » Does not bind a thread to a request » Uses Futures and Thread Pools to let CPU go at full throttle » Uses NIO.2 through Netty to avoid blocking on network IO » Stateless (no HTTP session) » No ThreadLocal anywhere

Slide 63

Slide 63 text

Future[Result] def index = Action.async { implicit request => Ok(...) }

Slide 64

Slide 64 text

Future[Result] » The async block indicates that the controller will return a Future[Result]

Slide 65

Slide 65 text

Future[Result] » The async block indicates that the controller will return a Future[Result] » The Future provides a way to do asynchronous handling but doesn't necessarily have to be non- blocking

Slide 66

Slide 66 text

Future[Result] » The async block indicates that the controller will return a Future[Result] » The Future provides a way to do asynchronous handling but doesn't necessarily have to be non- blocking » If a thread can't be deallocated while waiting for those other systems to respond, then it is blocking

Slide 67

Slide 67 text

Future[Result] » The async block indicates that the controller will return a Future[Result] » The Future provides a way to do asynchronous handling but doesn't necessarily have to be non- blocking » If a thread can't be deallocated while waiting for those other systems to respond, then it is blocking » Order of execution doesn't matter

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

Implications » ACID doesn't work across location/trust boundaries » No 2-Phase commits (2PC) » No holding locks for the duration of the work

Slide 71

Slide 71 text

Implications » Must embrace eventual consistency » Multiple workflows across multiple systems » Each provides a path of compensating actions

Slide 72

Slide 72 text

Saga pattern » a Saga splits work into individual transactions » effects can be reversed after work has been performed and commited

Slide 73

Slide 73 text

ConductR and Monitoring

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

How do I get started? https://www.typesafe.com/activator/download

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

Thank you! Kevin Webber Medium: medium.com/@kvnwbbr Twitter: @kvnwbbr Point of contact [email protected]