Igloos and Mountains.key

116
Taking AKKA to Production IGL S AND MOUNT NS

Transcript of Igloos and Mountains.key

Page 1: Igloos and Mountains.key

Taking AKKA to ProductionIGL S AND MOUNT NS

Page 2: Igloos and Mountains.key

Hello! I’m Derek Wyatt, Senior Platform Developer at Auvik Networks!and author of Akka Concurrency

Scala, Play and Akka form the foundational triad for Auvik Networks’ core technology. In this talk, we’ll discuss how Akka enables the asynchronous design of the system and how it powers the production environment.

THIS TALK

However, it’s not all cherries and moonbeams - we faced a number of challenges, including technological hurdles and more than a few spiky PEBKACs. You’ll hear how we overcame these issues, as well as provide some insight into how we’re growing our understanding and practices around the Typesafe platform.

Page 3: Igloos and Mountains.key

Auvik Networks

Auvik simplifies monitoring, configuring and automating small and medium sized enterprise networks. We help IT professionals build Networks That Work.TM

AUVIK AND THE TYPESAFE STACK

Page 4: Igloos and Mountains.key

Auvik Networks

Auvik simplifies monitoring, configuring and automating small and medium sized enterprise networks. We help IT professionals build Networks That Work.TM

Auvik is all in with Akka, Scala and Play - our future success is tied to the success of the Typesafe Platform. Akka’s design is what powers Auvik’s design.

AUVIK AND THE TYPESAFE STACK

Page 5: Igloos and Mountains.key

Hybrid Cloud SaaS

Auvik’s solution is half in the cloud and half on site

30K FOOT ARCHITECTURE

Page 6: Igloos and Mountains.key

Hybrid Cloud SaaS

Auvik’s solution is half in the cloud and half on site

The cloud provides the bulk of the operational logic and the on site software works on behalf of the cloud

30K FOOT ARCHITECTURE

Page 7: Igloos and Mountains.key

Hybrid Cloud SaaS

Auvik’s solution is half in the cloud and half on site

The cloud provides the bulk of the operational logic and the on site software works on behalf of the cloud

Technically, the on site software can operate disconnected from the cloud, but eventually it has to connect in, otherwise it’s working for nothing

30K FOOT ARCHITECTURE

Page 8: Igloos and Mountains.key

Hybrid Cloud SaaS

Auvik’s solution is half in the cloud and half on site

The cloud provides the bulk of the operational logic and the on site software works on behalf of the cloud

Technically, the on site software can operate disconnected from the cloud, but eventually it has to connect in, otherwise it’s working for nothing

While the on site component is an Akka solution, it does not communicate with the cloud using Akka protocols, since these aren’t design for the WAN

30K FOOT ARCHITECTURE

Page 9: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

AUVIK USES AKKA

Page 10: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Page 11: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Isolated

Page 12: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Resilient

Isolated

Page 13: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Asynchronous

Resilient

Isolated

Page 14: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Asynchronous

ResilientNon Blocking

Isolated

Page 15: Igloos and Mountains.key

Auvik’s core design is an Actor-based design

Customers exist in distinct Actor subtrees.

Tables, On Site connections, the Execution Engine, and many other components are all Actors

Those Actors ensure that our customer design is…

AUVIK USES AKKA

Asynchronous

ResilientNon Blocking

IsolatedReasonable

Page 16: Igloos and Mountains.key

The Cluster

CLOUD DEPLOYMENT

Page 17: Igloos and Mountains.key

The Cluster

We use Akka Clustering to manage our node fabric

CLOUD DEPLOYMENT

Page 18: Igloos and Mountains.key

The Cluster

We use Akka Clustering to manage our node fabric

Everything runs in Amazon, defined by CloudFormation and configured by Chef

CLOUD DEPLOYMENT

Page 19: Igloos and Mountains.key

The Cluster

We use Akka Clustering to manage our node fabric

Everything runs in Amazon, defined by CloudFormation and configured by Chef

Akka Clustering doesn’t survive across a WAN, so communication with the onsite component is proprietary

CLOUD DEPLOYMENT

Page 20: Igloos and Mountains.key

The Cluster

We use Akka Clustering to manage our node fabric

Everything runs in Amazon, defined by CloudFormation and configured by Chef

Akka Clustering doesn’t survive across a WAN, so communication with the onsite component is proprietary

Backends and Frontends are specified to scale independently

CLOUD DEPLOYMENT

Page 21: Igloos and Mountains.key

The Cluster

We use Akka Clustering to manage our node fabric

Everything runs in Amazon, defined by CloudFormation and configured by Chef

Akka Clustering doesn’t survive across a WAN, so communication with the onsite component is proprietary

Backends and Frontends are specified to scale independently

Cluster discovery happens through a well-known seed node (not shown)

CLOUD DEPLOYMENT

Page 22: Igloos and Mountains.key

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

CHALLENGES AND SURPRISES

Page 23: Igloos and Mountains.key

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

Inner classes and closures Inner classes and closures are awesome, unless they get caught up in messages and force us to serialize the planet

CHALLENGES AND SURPRISES

Page 24: Igloos and Mountains.key

Application Debugging asynchronous applications is still hard. Bulkhead your application to protect it from itself

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

Inner classes and closures Inner classes and closures are awesome, unless they get caught up in messages and force us to serialize the planet

CHALLENGES AND SURPRISES

Page 25: Igloos and Mountains.key

Application Debugging asynchronous applications is still hard. Bulkhead your application to protect it from itself

Performance issues Tracking down performance issues can be tough - that ForkJoin pool may not be your friend

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

Inner classes and closures Inner classes and closures are awesome, unless they get caught up in messages and force us to serialize the planet

CHALLENGES AND SURPRISES

Page 26: Igloos and Mountains.key

Play Framework Play doesn’t play nicely with Actor applications

Application Debugging asynchronous applications is still hard. Bulkhead your application to protect it from itself

Performance issues Tracking down performance issues can be tough - that ForkJoin pool may not be your friend

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

Inner classes and closures Inner classes and closures are awesome, unless they get caught up in messages and force us to serialize the planet

CHALLENGES AND SURPRISES

Page 27: Igloos and Mountains.key

Play Framework Play doesn’t play nicely with Actor applications

Future Correctness & Await.result Await.result is just evil. It’s not “sorta” evil… it’s the devil with the flu.

Application Debugging asynchronous applications is still hard. Bulkhead your application to protect it from itself

Performance issues Tracking down performance issues can be tough - that ForkJoin pool may not be your friend

Cluster Singletons Customers would be great Cluster Singletons, except Cluster Singletons don’t load balance

Inner classes and closures Inner classes and closures are awesome, unless they get caught up in messages and force us to serialize the planet

CHALLENGES AND SURPRISES

Page 28: Igloos and Mountains.key

Our own Cluster Singleton

MANAGING CLUSTER CUSTOMERS

Page 29: Igloos and Mountains.key

Our own Cluster Singleton

We created our own way of managing customers as “single instances”

MANAGING CLUSTER CUSTOMERS

Page 30: Igloos and Mountains.key

Our own Cluster Singleton

We created our own way of managing customers as “single instances”

The guy that manages the customers is a proper Akka Cluster Singleton

MANAGING CLUSTER CUSTOMERS

Page 31: Igloos and Mountains.key

Our own Cluster Singleton

We created our own way of managing customers as “single instances”

The guy that manages the customers is a proper Akka Cluster Singleton

He manages the instantiation of the customers on-demand

MANAGING CLUSTER CUSTOMERS

Page 32: Igloos and Mountains.key

Our own Cluster Singleton

We created our own way of managing customers as “single instances”

The guy that manages the customers is a proper Akka Cluster Singleton

He manages the instantiation of the customers on-demand

He also reacts to Akka Cluster events (new nodes, dead nodes, etc…) and can rebalance customers as required

MANAGING CLUSTER CUSTOMERS

Page 33: Igloos and Mountains.key

Scala makes this just too damn easy…

CLOSING OVER THE WORLD…

trait MyApp { case class Question(s: String) case class Answer(s: String) ! class Server extends Actor { def receive = { case Question(q) => sender ! Answer(s”Sup? $q”) } } class Client(server: ActorRef) extends Actor { server ! Question(“Dood!”) def receive = { case Answer(a) => println(s”Got $a”) } } }

Page 34: Igloos and Mountains.key

Scala makes this just too damn easy…

CLOSING OVER THE WORLD…

trait MyApp { case class Question(s: String) case class Answer(s: String) ! class Server extends Actor { def receive = { case Question(q) => sender ! Answer(s”Sup? $q”) } } class Client(server: ActorRef) extends Actor { server ! Question(“Dood!”) def receive = { case Answer(a) => println(s”Got $a”) } } }

Chances are that Question and

Answer won’t serialize

Page 35: Igloos and Mountains.key

Scala makes this just too damn easy…

CLOSING OVER THE WORLD…

trait MyApp { case class Question(s: String) case class Answer(s: String) ! class Server extends Actor { def receive = { case Question(q) => sender ! Answer(s”Sup? $q”) } } class Client(server: ActorRef) extends Actor { server ! Question(“Dood!”) def receive = { case Answer(a) => println(s”Got $a”) } } }

Chances are that Question and

Answer won’t serializeAnd even if they did,

they’d be huge

Page 36: Igloos and Mountains.key

PLAY DOESN’T PLAY NICELY

Modular Design

Page 37: Igloos and Mountains.key

PLAY DOESN’T PLAY NICELY

Modular DesignPlay doesn’t start like “just any other app”

Special developer modeSpecial run modeEither way, it’s “special”

Page 38: Igloos and Mountains.key

PLAY DOESN’T PLAY NICELY

Modular DesignPlay doesn’t start like “just any other app”

Special developer modeSpecial run modeEither way, it’s “special”

We want to start like a “normal” appBut not for developersFrontend needs to start backed when the Play Plugin starts

But not when it’s running in Frontend standalone mode

Page 39: Igloos and Mountains.key

PLAY DOESN’T PLAY NICELY

Modular DesignPlay doesn’t start like “just any other app”

Special developer modeSpecial run modeEither way, it’s “special”

We want to start like a “normal” appBut not for developersFrontend needs to start backed when the Play Plugin starts

But not when it’s running in Frontend standalone mode

Bootstrapping the configuration differs depending on how we start it

Page 40: Igloos and Mountains.key

PLAY DOESN’T PLAY NICELY

Modular DesignPlay doesn’t start like “just any other app”

Special developer modeSpecial run modeEither way, it’s “special”

We want to start like a “normal” appBut not for developersFrontend needs to start backed when the Play Plugin starts

But not when it’s running in Frontend standalone mode

Bootstrapping the configuration differs depending on how we start it

Modes for SBT

Main app for Production

IDE Configurations

Page 41: Igloos and Mountains.key

DEBUGGING IS HARD

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

Page 42: Igloos and Mountains.key

DEBUGGING IS HARD

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

Page 43: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

Page 44: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

Page 45: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

A chain of N futures can time out, but knowing which one timed out isn’t obvious

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

Page 46: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

A chain of N futures can time out, but knowing which one timed out isn’t obvious

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

We had race conditions that “shouldn’t be there”, but why?

Page 47: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

A chain of N futures can time out, but knowing which one timed out isn’t obvious

Message ordering guarantees are only between two Actors (adding a Future in the middle can warp your perception)

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

We had race conditions that “shouldn’t be there”, but why?

Page 48: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

A chain of N futures can time out, but knowing which one timed out isn’t obvious

Message ordering guarantees are only between two Actors (adding a Future in the middle can warp your perception)

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

We had race conditions that “shouldn’t be there”, but why?

We had Exceptions being thrown in messaging processors but messages sent by what?

Page 49: Igloos and Mountains.key

DEBUGGING IS HARD

The overhead of the Future had better be worth it!

A chain of N futures can time out, but knowing which one timed out isn’t obvious

Message ordering guarantees are only between two Actors (adding a Future in the middle can warp your perception)

Dropping a crappy message in a mailbox is perfectly correct; processing it is disconnected with queueing it

Captain Obvious…Akka makes writing concurrent software easier and clearer, but it doesn’t necessarily make it easier to debug

We had tons of work being done in the ForkJoin scheduler, but why?

We had a lot of timeouts occurring, but why?

We had race conditions that “shouldn’t be there”, but why?

We had Exceptions being thrown in messaging processors but messages sent by what?

Page 50: Igloos and Mountains.key

DEBUGGING IS HARD

Side effecting Futures

Page 51: Igloos and Mountains.key

DEBUGGING IS HARD

Side effecting FuturesIf you’re plumbing Futures to Actors, avoid side-effects doSomeDBThing() onSuccess {

case result => someActor ! result }

Horrendous!

Page 52: Igloos and Mountains.key

DEBUGGING IS HARD

Side effecting FuturesIf you’re plumbing Futures to Actors, avoid side-effects

Errors are lost, and onSuccess has no return value

doSomeDBThing() onSuccess { case result => someActor ! result }

Horrendous!

Page 53: Igloos and Mountains.key

DEBUGGING IS HARD

Side effecting FuturesIf you’re plumbing Futures to Actors, avoid side-effects

Errors are lost, and onSuccess has no return value

Always treat Futures as message transformers. Make a clear application protocol and stick with it

doSomeDBThing() onSuccess { case result => someActor ! result }

doSomeDBThing() map { result => DBResult(result) } recover { case t: Throwable => DBCallFailed(t) } pipeTo someActor

Horrendous!

Absolutely Lovely

Page 54: Igloos and Mountains.key

DEBUGGING IS HARD

Side effecting FuturesIf you’re plumbing Futures to Actors, avoid side-effects

Errors are lost, and onSuccess has no return value

Always treat Futures as message transformers. Make a clear application protocol and stick with it

This is easy to understand, catches the errors, and composes as well as asynchronous code can

doSomeDBThing() onSuccess { case result => someActor ! result }

doSomeDBThing() map { result => DBResult(result) } recover { case t: Throwable => DBCallFailed(t) } pipeTo someActor

Horrendous!

Absolutely Lovely

Page 55: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises

Page 56: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises“Most” of us shouldn’t be creating a promise

Page 57: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises“Most” of us shouldn’t be creating a promise

If you do, make damn sure you complete that promise

val p = Promise[String]() doSomeDBThing() foreach { result => val s = result.get(“someStringValue”) p.success(s) }

Horrendous!

Page 58: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises“Most” of us shouldn’t be creating a promise

If you do, make damn sure you complete that promise

Using the side effect operations on Futures (for example) is a pretty bad way to do it

val p = Promise[String]() doSomeDBThing() foreach { result => val s = result.get(“someStringValue”) p.success(s) }

Horrendous!

Page 59: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises“Most” of us shouldn’t be creating a promise

If you do, make damn sure you complete that promise

Using the side effect operations on Futures (for example) is a pretty bad way to do it

If you want to plumb a Future to a Promise, this is a much better approach

val p = Promise[String]() doSomeDBThing() foreach { result => val s = result.get(“someStringValue”) p.success(s) }

Horrendous!

Catches Everything

val p = Promise[String]() p.completeWith(doSomeDBThing() map { _.get(“someStringValue”) })

Page 60: Igloos and Mountains.key

DEBUGGING IS HARD

Broken Promises“Most” of us shouldn’t be creating a promise

If you do, make damn sure you complete that promise

Using the side effect operations on Futures (for example) is a pretty bad way to do it

If you want to plumb a Future to a Promise, this is a much better approach

If you’re not plumbing a Future to a Promise then you’re on your own to make sure it completes… don’t mess it up

val p = Promise[String]() doSomeDBThing() foreach { result => val s = result.get(“someStringValue”) p.success(s) }

Horrendous!

Catches Everything

val p = Promise[String]() p.completeWith(doSomeDBThing() map { _.get(“someStringValue”) })

Page 61: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost Sender

Page 62: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost SenderThink of the sender as the recipient of your response, not the subscriber to your stream

Page 63: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost SenderThink of the sender as the recipient of your response, not the subscriber to your stream

def receive = { case Subscribe() => addSubscriber(sender) sender ! Subscribed() }

Page 64: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost SenderThink of the sender as the recipient of your response, not the subscriber to your stream

So long as you always call it this way, you’re probably OK (although no guarantees)

def receive = { case Subscribe() => addSubscriber(sender) sender ! Subscribed() }

publisher ! Subscribe() def receive = { case Subscribed() => println(“Keen!”) }

OK

Page 65: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost SenderThink of the sender as the recipient of your response, not the subscriber to your stream

So long as you always call it this way, you’re probably OK (although no guarantees)

But what if you ask? You’re going to subscribe the temporary ask’s Actor!

def receive = { case Subscribe() => addSubscriber(sender) sender ! Subscribed() }

publisher ! Subscribe() def receive = { case Subscribed() => println(“Keen!”) }

publisher.ask(Subscribe()) .mapTo[Subscribed] .foreach(println)

OK

#Fail

Page 66: Igloos and Mountains.key

DEBUGGING IS HARD

The Lost SenderThink of the sender as the recipient of your response, not the subscriber to your stream

So long as you always call it this way, you’re probably OK (although no guarantees)

But what if you ask? You’re going to subscribe the temporary ask’s Actor!

The sender is just too flexible to treat this way, so make it part of your messaging protocol and you’re good to go

OK

def receive = { case Subscribe(subscriber) => addSubscriber(subscriber) sender ! Subscribed(subscriber) }

publisher ! Subscribe(self) def receive = { case Subscribed(`self`) => println(“Keen!”) }

publisher.ask(Subscribe(guy)) .mapTo[Subscribed] .foreach(println)

OK

Page 67: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite there

Page 68: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM 10% Effective

Page 69: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

10% Effective

30% Effective

Page 70: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

10% Effective

30% Effective

50% Effective

Page 71: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

10% Effective

30% Effective

50% Effective

Page 72: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Page 73: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Where did this Future come from?

Page 74: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Where did this Future come from?What Futures have yet to complete?

Page 75: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Where did this Future come from?What Futures have yet to complete?Is this Actor busy? Blocked?

Page 76: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Where did this Future come from?What Futures have yet to complete?Is this Actor busy? Blocked?Which Future timed out?

Page 77: Igloos and Mountains.key

LESS THAN AWESOME TOOLING

Tools aren’t quite thereWe used JVisualVM

We used YourKit

We built our own tools

Our tools help us debug the proprietary programming language and execution that we’ve created

That helps us understand how our “app” is working, but it’s also been quite effective to understand how Akka / Java is working

Bottom line… we’d still like better tools! :)

10% Effective

30% Effective

50% Effective

Where did this Future come from?What Futures have yet to complete?Is this Actor busy? Blocked?Which Future timed out?Where did this message come from?

Page 78: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

Page 79: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

When we start, we code quickly, and JDBC calls go on the same thread pool as everything else

Page 80: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

When we start, we code quickly, and JDBC calls go on the same thread pool as everything else

Your blocking calls start chewing up threads that Actors need

Page 81: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

When we start, we code quickly, and JDBC calls go on the same thread pool as everything else

Your blocking calls start chewing up threads that Actors need

So you increase the number of threads, and if they’re ForkJoin threads, well… we’ll get to that

Page 82: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

When we start, we code quickly, and JDBC calls go on the same thread pool as everything else

Your blocking calls start chewing up threads that Actors need

So you increase the number of threads, and if they’re ForkJoin threads, well… we’ll get to that

I think we did it right. Go fast, figure things out, then pull the foundations together once you know what you need done

Page 83: Igloos and Mountains.key

BULKHEAD!

One Thread Pool never works…

When we start, we code quickly, and JDBC calls go on the same thread pool as everything else

Your blocking calls start chewing up threads that Actors need

So you increase the number of threads, and if they’re ForkJoin threads, well… we’ll get to that

I think we did it right. Go fast, figure things out, then pull the foundations together once you know what you need done

The ExecutionContext is your friend!

Page 84: Igloos and Mountains.key

Managing Asynchrony

THREADS, FUTURES AND FORKJOIN

Page 85: Igloos and Mountains.key

Managing Asynchrony

THREADS, FUTURES AND FORKJOIN

Got Futures?

Page 86: Igloos and Mountains.key

Managing Asynchrony

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads?

Page 87: Igloos and Mountains.key

Managing Asynchrony

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

Page 88: Igloos and Mountains.key

Managing Asynchrony

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

! ! ! Haz Problemz!

Page 89: Igloos and Mountains.key

Managing AsynchronyThe ForkJoin Pool’s scheduler is O(n) in the number of threads

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

! ! ! Haz Problemz!

Page 90: Igloos and Mountains.key

Managing AsynchronyThe ForkJoin Pool’s scheduler is O(n) in the number of threads

If you need lots of threads, for whatever reason, then scheduling work on the FJ Pool becomes a non-trivial part of your computation

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

! ! ! Haz Problemz!

Page 91: Igloos and Mountains.key

Managing AsynchronyThe ForkJoin Pool’s scheduler is O(n) in the number of threads

If you need lots of threads, for whatever reason, then scheduling work on the FJ Pool becomes a non-trivial part of your computation

Do yourself a favour and configure a standard thread pool executor

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

! ! ! Haz Problemz!

Page 92: Igloos and Mountains.key

Managing AsynchronyThe ForkJoin Pool’s scheduler is O(n) in the number of threads

If you need lots of threads, for whatever reason, then scheduling work on the FJ Pool becomes a non-trivial part of your computation

Do yourself a favour and configure a standard thread pool executor

Our throughput doubled when we did that

THREADS, FUTURES AND FORKJOIN

Got Futures? Got (lotsa) Threads? Got ForkJoin?

! ! ! Haz Problemz!

Page 93: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronized

Page 94: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Page 95: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

Page 96: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

Page 97: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

If you’re waiting for the response to “Your Message”, how long are you gonna wait?

Page 98: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

If you’re waiting for the response to “Your Message”, how long are you gonna wait?

You’re waiting behind all the other messages in that mailbox, plus fighting for time from all the other Actors in the system

Page 99: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

If you’re waiting for the response to “Your Message”, how long are you gonna wait?

You’re waiting behind all the other messages in that mailbox, plus fighting for time from all the other Actors in the system

AND you’re chewing up a much-needed thread during that time!

Page 100: Igloos and Mountains.key

AWAIT AND DIE

Await != synchronizedSome people seem to think that an Await.result (on an Actor response) is like a synchronized block

Some people are silly :)

If you’re waiting for the response to “Your Message”, how long are you gonna wait?

You’re waiting behind all the other messages in that mailbox, plus fighting for time from all the other Actors in the system

AND you’re chewing up a much-needed thread during that time!

Auvik Bear Judges you!

Page 101: Igloos and Mountains.key

OUR RULES OF THUMB

Page 102: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Page 103: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Page 104: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Page 105: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Page 106: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Choose your thread pool types carefully (ForkJoin?)

Page 107: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Choose your thread pool types carefully (ForkJoin?)

sender is the message recipient, not the subscriber to a stream

Page 108: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Choose your thread pool types carefully (ForkJoin?)

sender is the message recipient, not the subscriber to a stream

Keep things simple and just “let it crash”

Page 109: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Choose your thread pool types carefully (ForkJoin?)

sender is the message recipient, not the subscriber to a stream

Keep things simple and just “let it crash”

Ask, “How does that work when we’re clustered?”

Page 110: Igloos and Mountains.key

OUR RULES OF THUMB

Avoid nested classes to help serialization

Never use Await… well, you can in tests

Keep Futures as pure as possible; no side-effects

Bulkhead your IO and other nasty code

Choose your thread pool types carefully (ForkJoin?)

sender is the message recipient, not the subscriber to a stream

Keep things simple and just “let it crash”

Ask, “How does that work when we’re clustered?”

Instrument your code and measure, measure, Measure!

Page 111: Igloos and Mountains.key

WE’RE HAPPY!

Akka powers our worldOur distributed, asynchronous design is an Akka design

Page 112: Igloos and Mountains.key

WE’RE HAPPY!

Akka powers our worldOur distributed, asynchronous design is an Akka design

Clustering and scaling out isn’t a simple “side effect” of coding in Akka, but it’s heavily simplified

Page 113: Igloos and Mountains.key

WE’RE HAPPY!

Akka powers our worldOur distributed, asynchronous design is an Akka design

Clustering and scaling out isn’t a simple “side effect” of coding in Akka, but it’s heavily simplified

Message-based network-oriented programming is the killer paradigm for the cloud

Page 114: Igloos and Mountains.key

WE’RE HAPPY!

Akka powers our worldOur distributed, asynchronous design is an Akka design

Clustering and scaling out isn’t a simple “side effect” of coding in Akka, but it’s heavily simplified

Message-based network-oriented programming is the killer paradigm for the cloud

Akka has allowed us to program defensively by simply adopting the “let it crash” philosophy

Page 115: Igloos and Mountains.key

WE’RE HAPPY!

Akka powers our worldOur distributed, asynchronous design is an Akka design

Clustering and scaling out isn’t a simple “side effect” of coding in Akka, but it’s heavily simplified

Message-based network-oriented programming is the killer paradigm for the cloud

Akka has allowed us to program defensively by simply adopting the “let it crash” philosophy

Basically… we’re quite happy :)

Page 116: Igloos and Mountains.key

Networks That Work.™