SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
Effective	
  Actors
                              Jamie	
  Allen




Friday, January 11, 13
Who	
  Am	
  I?

         •Consultant	
  at	
  Typesafe
         •Actor	
  &	
  Scala	
  developer	
  since	
  2009

                         jamie.allen@typesafe.com


                                                              @jamie_allen
Friday, January 11, 13
Effective	
  Actors

         •Best	
  practices	
  based	
  on	
  several	
  years	
  of	
  actor	
  
                 development
         •Helpful	
  hints	
  for	
  reasoning	
  about	
  actors	
  at	
  runtime



                                                                            @jamie_allen
Friday, January 11, 13
Actors
             •Concurrent,	
                                 A
                     lightweight	
  
                     processes	
  that	
  
                     communicate	
                      B       C

                     through	
  
                     asynchronous	
                         D
                     message	
  passing

             •Isolation	
  of	
  state,	
  no	
     E       F         G
                     internal	
  concurrency

                                                                @jamie_allen
Friday, January 11, 13
Akka	
  Actors
        class Pinger extends Actor {
          def receive = {
            case _ => println("Pinging!"); sender ! "Ping!"
          }
        }

        class Ponger extends Actor {
          def receive = {
            case _ => println("Ponging!"); sender ! "Pong!"
          }
        }

        object PingPong extends App {
          val system = ActorSystem()
          val pinger = system.actorOf(Props[Pinger])
          val ponger = system.actorOf(Props[Ponger])
          pinger.tell("Ping!", ponger)
          Thread.sleep(1000)
          system.shutdown
        }



                                                              @jamie_allen
Friday, January 11, 13
Akka	
  Actors
        class Pinger extends Actor {
          def receive = {
            case _ => println("Pinging!"); sender ! "Ping!"
          }
        }

        class Ponger extends Actor {
          def receive = {
            case _ => println("Ponging!"); sender ! "Pong!"
          }
        }

        object PingPong extends App {
          val system = ActorSystem()
          val pinger = system.actorOf(Props[Pinger])
          val ponger = system.actorOf(Props[Ponger])
          pinger.tell("Ping!", ponger)
          Thread.sleep(1000)
          system.shutdown
        }



                                                              @jamie_allen
Friday, January 11, 13
Akka	
  Actors
        class Pinger extends Actor {
          def receive = {
            case _ => println("Pinging!"); sender ! "Ping!"
          }
        }

        class Ponger extends Actor {
          def receive = {
            case _ => println("Ponging!"); sender ! "Pong!"
          }
        }

        object PingPong extends App {
          val system = ActorSystem()
          val pinger = system.actorOf(Props[Pinger])
          val ponger = system.actorOf(Props[Ponger])
          pinger.tell("Ping!", ponger)
          Thread.sleep(1000)
          system.shutdown
        }



                                                              @jamie_allen
Friday, January 11, 13
Akka	
  Actors
        class Pinger extends Actor {
          def receive = {
            case _ => println("Pinging!"); sender ! "Ping!"
          }
        }

        class Ponger extends Actor {
          def receive = {
            case _ => println("Ponging!"); sender ! "Pong!"
          }
        }

        object PingPong extends App {
          val system = ActorSystem()
          val pinger = system.actorOf(Props[Pinger])
          val ponger = system.actorOf(Props[Ponger])
          pinger.tell("Ping!", ponger)
          Thread.sleep(1000)
          system.shutdown
        }
                           Overriding the “sender”
                                                              @jamie_allen
Friday, January 11, 13
Supervisor	
  Hierarchies
                                                             A



             •Specifies	
  handling	
                     B       C
                     mechanisms	
  for	
  
                     groupings	
  of	
  actors	
  
                     in	
  parent/child	
                    D

                     relationship
                                                     E       F         G




                                                                 @jamie_allen
Friday, January 11, 13
Akka	
  Supervisors

        class MySupervisor extends Actor {
          override val supervisorStrategy =
            OneForOneStrategy() {
              case ae: ArithmeticException => Resume
              case np: NullPointerException => Restart
            }

             context.actorOf(Props[MyActor])
        }




                                                         @jamie_allen
Friday, January 11, 13
Akka	
  Supervisors

        class MySupervisor extends Actor {
          override val supervisorStrategy =
            OneForOneStrategy() {
              case ae: ArithmeticException => Resume
              case np: NullPointerException => Restart
            }

             context.actorOf(Props[MyActor])
        }




                                                         @jamie_allen
Friday, January 11, 13
Akka	
  Supervisors

        class MySupervisor extends Actor {
          override val supervisorStrategy =
            OneForOneStrategy() {
              case ae: ArithmeticException => Resume
              case np: NullPointerException => Restart
            }

             context.actorOf(Props[MyActor])
        }




            Note the “context”

                                                         @jamie_allen
Friday, January 11, 13
Domain	
  Supervision

         •Each	
  supervisor	
  manages	
  a	
  grouping	
  of	
  types	
  in	
  
                 a	
  domain

         •Actors	
  persist	
  to	
  represent	
  existence	
  of	
  
                 instances	
  and	
  contain	
  their	
  own	
  state

         •Actors	
  constantly	
  resolve	
  the	
  world	
  as	
  it	
  should	
  
                 be	
  against	
  the	
  world	
  as	
  it	
  is


                                                                        @jamie_allen
Friday, January 11, 13
Worker	
  Supervision
         •Supervisors	
  should	
  hold	
  all	
  critical	
  data
         •Workers	
  should	
  receive	
  data	
  for	
  tasks	
  in	
  
                 messages

         •Workers	
  being	
  supervised	
  should	
  perform	
  
                 dangerous	
  tasks

         •Supervisor	
  should	
  know	
  how	
  to	
  handle	
  failures	
  
                 in	
  workers	
  in	
  order	
  to	
  retry	
  appropriately

                                                                            @jamie_allen
Friday, January 11, 13
Parallelism
             •Easily	
  scale	
  a	
  task	
  by	
                A
                     creating	
  multiple	
  
                     instances	
  of	
  an	
  actor	
  
                     and	
  applying	
  work	
                B       C

                     using	
  various	
  
                     strategies                                   D


             •Order	
  is	
  not	
  
                     guaranteed,	
  nor	
                 E       F         G
                     should	
  it	
  be

                                                                      @jamie_allen
Friday, January 11, 13
Akka	
  Routing

        class MyActor extends Actor {
          def receive = { case x => println(x) }
        }

        object Parallelizer extends App {
          val system = ActorSystem()
          val router: ActorRef = system.actorOf(Props[MyActor].
            withRouter(RoundRobinRouter(nrOfInstances = 5)))

             for (i <- 1 to 10) router ! i
        }




                                                                  @jamie_allen
Friday, January 11, 13
Akka	
  Routing

        class MyActor extends Actor {
          def receive = { case x => println(x) }
        }

        object Parallelizer extends App {
          val system = ActorSystem()
          val router: ActorRef = system.actorOf(Props[MyActor].
            withRouter(RoundRobinRouter(nrOfInstances = 5)))

             for (i <- 1 to 10) router ! i
        }




                                                                  @jamie_allen
Friday, January 11, 13
Akka	
  Routing

        class MyActor extends Actor {
          def receive = { case x => println(x) }
        }

        object Parallelizer extends App {
          val system = ActorSystem()
          val router: ActorRef = system.actorOf(Props[MyActor].
            withRouter(RoundRobinRouter(nrOfInstances = 5)))

             for (i <- 1 to 10) router ! i
        }


                                     Should be configured externally


                                                                  @jamie_allen
Friday, January 11, 13
Akka	
  Routing

        class MyActor extends Actor {
          def receive = { case x => println(x) }
        }

        object Parallelizer extends App {
          val system = ActorSystem()
          val router: ActorRef = system.actorOf(Props[MyActor].
            withRouter(RoundRobinRouter(nrOfInstances = 5)))

             for (i <- 1 to 10) router ! i
        }




                                                                  @jamie_allen
Friday, January 11, 13
RULE:
              Actors Should Only Do One Thing




                                          @jamie_allen
Friday, January 11, 13
Single	
  Responsibility	
  Principle

         •Do	
  not	
  conflate	
  responsibilities	
  in	
  actors
         •Becomes	
  hard	
  to	
  define	
  the	
  boundaries	
  of	
  
                 responsibility

         •Supervision	
  becomes	
  more	
  difficult	
  as	
  you	
  
                 handle	
  more	
  possibilities

         •Debugging	
  becomes	
  very	
  difficult
                                                                    @jamie_allen
Friday, January 11, 13
Supervision


         •Every	
  non-­‐leaf	
  node	
  is	
  technically	
  a	
  supervisor
         •Create	
  explicit	
  supervisors	
  under	
  each	
  node	
  for	
  
                 each	
  type	
  of	
  child	
  to	
  be	
  managed




                                                                      @jamie_allen
Friday, January 11, 13
Conflated	
  Supervision

           C1                               C2                             Customers



                                                                          Accounts &
                           Ac1   Ac2        D1        D2        D3
                                                                           Devices




                                       A1        A2        A3        A4   Applications




                                                                          @jamie_allen
Friday, January 11, 13
Explicit	
  Supervision

                C1                               C2                                  Customers


                                                                DS                  Accounts &
                                 AS
                                                                                     Devices




                         Ac1          Ac2             D1        D2        D3




                                            A1             A2        A3        A4   Applications

                                                                                    @jamie_allen
Friday, January 11, 13
Keep	
  the	
  Error	
  Kernel	
  Simple

         •Limit	
  the	
  number	
  of	
  supervisors	
  you	
  create	
  at	
  
                 this	
  level

         •Helps	
  with	
  fault	
  tolerance	
  and	
  explicit	
  handling	
  
                 of	
  errors	
  through	
  the	
  hierarchy

         •Akka	
  uses	
  synchronous	
  messaging	
  to	
  create	
  
                 top-­‐level	
  actors


                                                                       @jamie_allen
Friday, January 11, 13
Use	
  Failure	
  Zones

         •Multiple	
  isolated	
  zones	
  with	
  their	
  own	
  
                 resources	
  (thread	
  pools,	
  etc)

         •Prevents	
  starvation	
  of	
  actors
         •Prevents	
  issues	
  in	
  one	
  branch	
  from	
  affecting	
  
                 another



                                                                      @jamie_allen
Friday, January 11, 13
Failure	
  Zones

                C1                         C2                             Customers


                         AS                          DS                  Accounts &
                                                                          Devices




                   Ac1        Ac2          D1        D2        D3




                                      A1        A2        A3        A4   Applications


                                                                         @jamie_allen
Friday, January 11, 13
Failure	
  Zones

                C1                         C2                             Customers


                         AS                          DS                  Accounts &
                                                                          Devices




                   Ac1        Ac2          D1        D2        D3




                                      A1        A2        A3        A4   Applications


                                                                         @jamie_allen
Friday, January 11, 13
Takeaway

         •Isolation	
  of	
  groups	
  of	
  actors	
  limits	
  the	
  effects	
  
                 of	
  failure

         •For	
  reasonably	
  complex	
  actor	
  systems,	
  shallow	
  
                 trees	
  are	
  a	
  smell	
  test

         •Actors	
  are	
  cheap	
  -­‐	
  use	
  them

                                                                         @jamie_allen
Friday, January 11, 13
RULE:
     Block Only When and Where You Must




                                  @jamie_allen
Friday, January 11, 13
Consequences	
  of	
  Blocking


         •Eventually	
  results	
  in	
  actor	
  starvation	
  as	
  thread	
  
                 pool	
  dries	
  up

         •Horrible	
  performance
         •Massive	
  waste	
  of	
  system	
  resources

                                                                       @jamie_allen
Friday, January 11, 13
Futures
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker])
          def receive = {
            case _ =>
              worker ? (1 to 100) map
                (x => println("Got value: %d".format(x)))
          }
        }

        object Bootstrapper extends App {
          val system = ActorSystem()
          val delegator = system.actorOf(Props[Delegator])
          delegator ! "Start"
          Thread.sleep(1000)
          system.shutdown
        }

                                                             @jamie_allen
Friday, January 11, 13
Futures
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker])
          def receive = {
            case _ =>
              worker ? (1 to 100) map
                (x => println("Got value: %d".format(x)))
          }
        }

        object Bootstrapper extends App {
          val system = ActorSystem()
          val delegator = system.actorOf(Props[Delegator])
          delegator ! "Start"
          Thread.sleep(1000)
          system.shutdown
        }

                                                             @jamie_allen
Friday, January 11, 13
Futures
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker])
          def receive = {
            case _ =>
              worker ? (1 to 100) map
                (x => println("Got value: %d".format(x)))
          }
        }

        object Bootstrapper extends App {
          val system = ActorSystem()
          val delegator = system.actorOf(Props[Delegator])
          delegator ! "Start"
          Thread.sleep(1000)
          system.shutdown
        }

                                                             @jamie_allen
Friday, January 11, 13
Futures
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker])
          def receive = {
            case _ =>
              worker ? (1 to 100) map
                (x => println("Got value: %d".format(x)))
          }
        }

        object Bootstrapper extends App {
          val system = ActorSystem()
          val delegator = system.actorOf(Props[Delegator])
          delegator ! "Start"
          Thread.sleep(1000)
          system.shutdown
        }

                                                             @jamie_allen
Friday, January 11, 13
Futures
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker])
          def receive = {
            case _ =>
              worker ? (1 to 100) map
                (x => println("Got value: %d".format(x)))
          }
        }

        object Bootstrapper extends App {
          val system = ActorSystem()
          val delegator = system.actorOf(Props[Delegator])
          delegator ! "Start"
          Thread.sleep(1000)
          system.shutdown
        }

                                                             @jamie_allen
Friday, January 11, 13
Sequential	
  Futures


        val r: Future[Int] = for {
          a <- (service1 ? GetResult).mapTo[Int]
          b <- (service2 ? GetResult(a)).mapTo[Int]
        } yield a * b




                                                      @jamie_allen
Friday, January 11, 13
Sequential	
  Futures

                                 Type Safety

        val r: Future[Int] = for {
          a <- (service1 ? GetResult).mapTo[Int]
          b <- (service2 ? GetResult(a)).mapTo[Int]
        } yield a * b




                                                      @jamie_allen
Friday, January 11, 13
Parallel	
  Futures

        First way: Define futures first
        val f1: Future[Int] = service1 ? GetResult
        val f2: Future[Int] = service2 ? GetResult

        val r: Future[Int] = for {
          a <- f1
          b <- f2
        } yield a * b




                                                     @jamie_allen
Friday, January 11, 13
Parallel	
  Futures


     Second way: Define in one line of for comprehension
      val r: Future[Int] = for {
        (a: Int, b: Int) <- (service1 ? GetResult) zip (service2 ? GetResult)
      } yield a * b




                                                   Note the “zip”



                                                                   @jamie_allen
Friday, January 11, 13
Blocking
         •An	
  example	
  is	
  database	
  access
         •Use	
  a	
  specialized	
  actor	
  with	
  its	
  own	
  resources
         •Pass	
  messages	
  to	
  other	
  actors	
  to	
  handle	
  the	
  
                 result

         •Akka	
  provides	
  “Managed	
  Blocking”	
  to	
  limit	
  the	
  
                 number	
  of	
  blocking	
  operations	
  taking	
  place	
  in	
  
                 actors	
  at	
  one	
  time

                                                                           @jamie_allen
Friday, January 11, 13
Akka	
  Dispatcher
        class Worker extends Actor {
          def receive = {
            case s: Seq[Int] => sender ! s.reduce(_ + _)
          }
        }

        class Delegator extends Actor {
          implicit val timeout: Timeout = 2 seconds
          val worker = context.actorOf(Props[Worker]).
            withDispatcher(“my-dispatcher”)
                                                             Failure
          def receive = {
            case _ =>
                                                              Zone
              blocking {
                val futResult = worker ? (1 to 100)
                val result = Await.result(futResult, 2 seconds)
              }
          }
        }




                                                                  @jamie_allen
Friday, January 11, 13
Push,	
  Not	
  Pull

         •Start	
  with	
  no	
  guarantees	
  about	
  delivery
         •Add	
  guarantees	
  only	
  where	
  you	
  need	
  them
         •Retry	
  until	
  you	
  get	
  the	
  answer	
  you	
  expect
         •Switch	
  your	
  actor	
  to	
  a	
  "nominal"	
  state	
  at	
  that	
  
                 point



                                                                           @jamie_allen
Friday, January 11, 13
Takeaway


         •Find	
  ways	
  to	
  ensure	
  that	
  your	
  actors	
  remain	
  
                 asynchronous	
  and	
  non-­‐blocking

         •Avoid	
  making	
  your	
  actors	
  wait	
  for	
  anything	
  
                 while	
  handling	
  a	
  message




                                                                        @jamie_allen
Friday, January 11, 13
RULE:
                         Do Not Optimize Prematurely




                                                   @jamie_allen
Friday, January 11, 13
Start	
  Simple


         •Make	
  Donald	
  Knuth	
  happy
         •Start	
  with	
  a	
  simple	
  configuration	
  and	
  profile
         •Do	
  not	
  parallelize	
  until	
  you	
  know	
  you	
  need	
  to	
  
                 and	
  where




                                                                          @jamie_allen
Friday, January 11, 13
Initial	
  Focus

         •Deterministic
         •Declarative
         •Immutable
         •Start	
  with	
  functional	
  programming	
  and	
  go	
  
                 from	
  there



                                                                  @jamie_allen
Friday, January 11, 13
Advice	
  From	
  Jonas	
  Bonér

         •Layer	
  in	
  complexity
         •Add	
  indeterminism
         •Add	
  mutability	
  in	
  hot	
  spots	
  
                 (CAS	
  and	
  STM)

         •Add	
  explicit	
  locking	
  and	
  
                 threads	
  as	
  a	
  last	
  resort   Photo courtesy of Brian Clapper, NE Scala 2011




                                                                              @jamie_allen
Friday, January 11, 13
Prepare	
  for	
  Race	
  Conditions

         •Write	
  actor	
  code	
  to	
  be	
  agnostic	
  of	
  time	
  and	
  
                 order

         •Actors	
  should	
  only	
  care	
  about	
  now,	
  not	
  that	
  
                 something	
  happened	
  before	
  it

         •Actors	
  can	
  "become"	
  or	
  represent	
  state	
  
                 machines	
  to	
  represent	
  transitions


                                                                           @jamie_allen
Friday, January 11, 13
Beware	
  the	
  Thundering	
  Herd
         •Actor	
  systems	
  can	
  be	
  overwhelmed	
  by	
  "storms"	
  of	
  
                 messages	
  flying	
  about

         •Do	
  not	
  pass	
  generic	
  messages	
  that	
  apply	
  to	
  many	
  
                 actors

         •Dampen	
  actor	
  messages	
  if	
  the	
  exact	
  same	
  message	
  is	
  
                 being	
  handled	
  repeatedly	
  within	
  a	
  certain	
  timeframe

         •Tune	
  your	
  dispatchers	
  and	
  mailboxes	
  via	
  back-­‐off	
  
                 policies	
  and	
  queue	
  sizes

         •Akka	
  now	
  has	
  Circuit	
  Breakers
                                                                              @jamie_allen
Friday, January 11, 13
Takeaway


         •Start	
  by	
  thinking	
  in	
  terms	
  of	
  an	
  implementation	
  
                 that	
  is	
  deterministic	
  and	
  not	
  actor	
  based

         •Layer	
  in	
  complexity	
  as	
  you	
  go


                                                                               @jamie_allen
Friday, January 11, 13
RULE:
                         Be Explicit In Your Intent




                                                      @jamie_allen
Friday, January 11, 13
Name	
  Your	
  Actors
         •Allows	
  for	
  external	
  configuration
         •Allows	
  for	
  lookup
         •Better	
  semantic	
  logging

            val system = ActorSystem("pingpong")
            val pinger = system.actorOf(Props[Pinger], "pinger")
            val ponger = system.actorOf(Props[Ponger], "ponger")




                                                                   @jamie_allen
Friday, January 11, 13
Create	
  Specialized	
  Messages
         •Non-­‐specific	
  messages	
  about	
  general	
  events	
  
                 are	
  dangerous
                                       AccountsUpdated

         •Can	
  result	
  in	
  "event	
  storms"	
  as	
  all	
  actors	
  react	
  to	
  
                 them

         •Use	
  specific	
  messages	
  forwarded	
  to	
  actors	
  for	
  
                 handling
                         AccountDeviceAdded(acctNum, deviceNum)



                                                                             @jamie_allen
Friday, January 11, 13
Create	
  Specialized	
  Exceptions


         •Don't	
  use	
  java.lang.Exception	
  to	
  represent	
  
                 failure	
  in	
  an	
  actor

         •Specific	
  exceptions	
  can	
  be	
  handled	
  explicitly
         •State	
  can	
  be	
  transferred	
  between	
  actor	
  
                 incarnations	
  in	
  Akka	
  (if	
  need	
  be)



                                                                    @jamie_allen
Friday, January 11, 13
Takeaway

         •Be	
  specific	
  in	
  everything	
  you	
  do
         •Makes	
  everything	
  that	
  occurs	
  in	
  your	
  actor	
  
                 system	
  more	
  clear	
  to	
  other	
  developers	
  
                 maintaining	
  the	
  code

         •Makes	
  everything	
  more	
  clear	
  in	
  production

                                                                            @jamie_allen
Friday, January 11, 13
RULE:
                         Do Not Expose Your Actors




                                                     @jamie_allen
Friday, January 11, 13
No	
  Direct	
  References

         •Actors	
  die
         •Doesn't	
  prevent	
  someone	
  from	
  calling	
  into	
  an	
  
                 actor	
  with	
  another	
  thread

         •Akka	
  solves	
  this	
  with	
  the	
  ActorRef	
  abstraction
         •Erlang	
  solves	
  this	
  with	
  PIDs

                                                                   @jamie_allen
Friday, January 11, 13
Never	
  Publish	
  “this”

         •Don't	
  send	
  it	
  anywhere
         •Don't	
  register	
  it	
  anywhere
         •Particularly	
  with	
  future	
  callbacks
         •Publish	
  “self”	
  instead,	
  which	
  is	
  an	
  ActorRef
         •Avoid	
  closing	
  over	
  "sender"	
  in	
  Akka,	
  it	
  will	
  
                 change	
  with	
  the	
  next	
  message


                                                                          @jamie_allen
Friday, January 11, 13
Use	
  Immutable	
  Messages


         •Enforces	
  which	
  actor	
  owns	
  the	
  data
         •If	
  mutable	
  state	
  can	
  escape,	
  what	
  is	
  the	
  point	
  
                 of	
  using	
  an	
  actor?




                                                                           @jamie_allen
Friday, January 11, 13
Pass	
  Copies	
  of	
  Mutable	
  Data

         •Mutable	
  data	
  in	
  actors	
  is	
  fine
         •But	
  data	
  can	
  escape	
  your	
  scope
         •Copy	
  the	
  data	
  and	
  pass	
  that,	
  as	
  Erlang	
  does	
  
                 (COW)

         •Akka	
  has	
  STM	
  references

                                                                           @jamie_allen
Friday, January 11, 13
Avoid	
  Sending	
  Behavior


         •Unless	
  using	
  Agents,	
  of	
  course
         •Closures	
  make	
  this	
  possible	
  (and	
  easy)
         •Also	
  makes	
  it	
  easy	
  for	
  state	
  to	
  escape


                                                                        @jamie_allen
Friday, January 11, 13
Takeaway


         •Keep	
  everything	
  about	
  an	
  actor	
  internal	
  to	
  that	
  
                 actor

         •Be	
  vary	
  wary	
  of	
  data	
  passed	
  in	
  closures	
  to	
  
                 anyone	
  else




                                                                             @jamie_allen
Friday, January 11, 13
RULE:
                 Make Debugging Easy On Yourself




                                             @jamie_allen
Friday, January 11, 13
Externalize	
  Business	
  Logic

         •Consider	
  using	
  external	
  functions	
  to	
  
                 encapsulate	
  complex	
  business	
  logic

         •Easier	
  to	
  unit	
  test	
  outside	
  of	
  actor	
  context
         •Not	
  a	
  rule	
  of	
  thumb,	
  but	
  something	
  to	
  consider	
  
                 as	
  complexity	
  increases

         •Not	
  as	
  big	
  of	
  an	
  issue	
  with	
  Akka's	
  TestKit
                                                                           @jamie_allen
Friday, January 11, 13
Use	
  Semantically	
  Useful	
  Logging


         •Trace-­‐level	
  logs	
  should	
  have	
  output	
  that	
  you	
  
                 can	
  read	
  easily

         •Use	
  line-­‐breaks	
  and	
  indentation
         •Both	
  Akka	
  and	
  Erlang	
  support	
  hooking	
  in	
  
                 multiple	
  listeners	
  to	
  the	
  event	
  log	
  stream



                                                                            @jamie_allen
Friday, January 11, 13
Unique	
  IDs	
  for	
  Messages
         •Allows	
  you	
  to	
  track	
  message	
  flow
         •When	
  you	
  find	
  a	
  problem,	
  get	
  the	
  ID	
  of	
  the	
  
                 message	
  that	
  led	
  to	
  it

         •Use	
  the	
  ID	
  to	
  grep	
  your	
  logs	
  and	
  display	
  output	
  
                 just	
  for	
  that	
  message	
  flow

         •Akka	
  ensures	
  ordering	
  on	
  a	
  per	
  actor	
  basis,	
  also	
  
                 in	
  logging

                                                                             @jamie_allen
Friday, January 11, 13
Monitor	
  Everything
         •Do	
  it	
  from	
  the	
  start
         •Use	
  tools	
  like	
  JMX	
  MBeans	
  to	
  visualize	
  actor	
  
                 realization

         •The	
  Typesafe	
  Console	
  is	
  a	
  great	
  tool	
  to	
  visualize	
  
                 actor	
  systems,	
  doesn't	
  require	
  you	
  to	
  do	
  
                 anything	
  up	
  front

         •Visual	
  representations	
  of	
  actor	
  systems	
  at	
  
                 runtime	
  are	
  invaluable

                                                                              @jamie_allen
Friday, January 11, 13
Typesafe	
  Console




                                               @jamie_allen
Friday, January 11, 13
Takeaway


         •Build	
  your	
  actor	
  system	
  to	
  be	
  maintainable	
  
                 from	
  the	
  outset

         •Utilize	
  all	
  of	
  the	
  tools	
  at	
  your	
  disposal


                                                                           @jamie_allen
Friday, January 11, 13
Thank	
  You!

         •Some	
  content	
  provided	
  by	
  members	
  of	
  the	
  
                 Typesafe	
  team,	
  including:

               •Jonas	
  Bonér
               •Viktor	
  Klang
               •Roland	
  Kuhn
               •Havoc	
  Pennington
                                                                  @jamie_allen
Friday, January 11, 13

Más contenido relacionado

Destacado

1966 frank-development of underdevelopment
1966 frank-development of underdevelopment1966 frank-development of underdevelopment
1966 frank-development of underdevelopmentHira Masood
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedDaniel Sawano
 
The no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkThe no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkAdam Warski
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingGarth Gilmour
 
Actor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in AkkaActor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in Akkadrewhk
 
Effective akka scalaio
Effective akka scalaioEffective akka scalaio
Effective akka scalaioshinolajla
 
Efficient HTTP Apis
Efficient HTTP ApisEfficient HTTP Apis
Efficient HTTP ApisAdrian Cole
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!priort
 
C*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraC*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraDataStax
 
Building ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudBuilding ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudIdan Fridman
 
A Scala Corrections Library
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections LibraryPaul Phillips
 
Lightning Talk: Running MongoDB on Docker for High Performance Deployments
Lightning Talk: Running MongoDB on Docker for High Performance DeploymentsLightning Talk: Running MongoDB on Docker for High Performance Deployments
Lightning Talk: Running MongoDB on Docker for High Performance DeploymentsMongoDB
 
Future of ai on the jvm
Future of ai on the jvmFuture of ai on the jvm
Future of ai on the jvmAdam Gibson
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solrpittaya
 
Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)mircodotta
 
Scala Json Features and Performance
Scala Json Features and PerformanceScala Json Features and Performance
Scala Json Features and PerformanceJohn Nestor
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play appsYevgeniy Brikman
 
Stateful Distributed Stream Processing
Stateful Distributed Stream ProcessingStateful Distributed Stream Processing
Stateful Distributed Stream ProcessingGyula Fóra
 
An example of Future composition in a real app
An example of Future composition in a real appAn example of Future composition in a real app
An example of Future composition in a real appPhil Calçado
 

Destacado (20)

1966 frank-development of underdevelopment
1966 frank-development of underdevelopment1966 frank-development of underdevelopment
1966 frank-development of underdevelopment
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons Learned
 
The no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection FrameworkThe no-framework Scala Dependency Injection Framework
The no-framework Scala Dependency Injection Framework
 
A Sceptical Guide to Functional Programming
A Sceptical Guide to Functional ProgrammingA Sceptical Guide to Functional Programming
A Sceptical Guide to Functional Programming
 
Actor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in AkkaActor Based Asyncronous IO in Akka
Actor Based Asyncronous IO in Akka
 
Effective akka scalaio
Effective akka scalaioEffective akka scalaio
Effective akka scalaio
 
Efficient HTTP Apis
Efficient HTTP ApisEfficient HTTP Apis
Efficient HTTP Apis
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
C*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with CassandraC*ollege Credit: Creating Your First App in Java with Cassandra
C*ollege Credit: Creating Your First App in Java with Cassandra
 
Building ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloudBuilding ‘Bootiful’ microservices cloud
Building ‘Bootiful’ microservices cloud
 
A Scala Corrections Library
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections Library
 
Lightning Talk: Running MongoDB on Docker for High Performance Deployments
Lightning Talk: Running MongoDB on Docker for High Performance DeploymentsLightning Talk: Running MongoDB on Docker for High Performance Deployments
Lightning Talk: Running MongoDB on Docker for High Performance Deployments
 
Future of ai on the jvm
Future of ai on the jvmFuture of ai on the jvm
Future of ai on the jvm
 
Curator intro
Curator introCurator intro
Curator intro
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solr
 
Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)Effective Scala (SoftShake 2013)
Effective Scala (SoftShake 2013)
 
Scala Json Features and Performance
Scala Json Features and PerformanceScala Json Features and Performance
Scala Json Features and Performance
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
Stateful Distributed Stream Processing
Stateful Distributed Stream ProcessingStateful Distributed Stream Processing
Stateful Distributed Stream Processing
 
An example of Future composition in a real app
An example of Future composition in a real appAn example of Future composition in a real app
An example of Future composition in a real app
 

Más de shinolajla

20180416 reactive is_a_product_rs
20180416 reactive is_a_product_rs20180416 reactive is_a_product_rs
20180416 reactive is_a_product_rsshinolajla
 
20180416 reactive is_a_product
20180416 reactive is_a_product20180416 reactive is_a_product
20180416 reactive is_a_productshinolajla
 
20161027 scala io_keynote
20161027 scala io_keynote20161027 scala io_keynote
20161027 scala io_keynoteshinolajla
 
20160609 nike techtalks reactive applications tools of the trade
20160609 nike techtalks reactive applications   tools of the trade20160609 nike techtalks reactive applications   tools of the trade
20160609 nike techtalks reactive applications tools of the tradeshinolajla
 
20160524 ibm fast data meetup
20160524 ibm fast data meetup20160524 ibm fast data meetup
20160524 ibm fast data meetupshinolajla
 
20160520 The Future of Services
20160520 The Future of Services20160520 The Future of Services
20160520 The Future of Servicesshinolajla
 
20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdas20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdasshinolajla
 
20160317 lagom sf scala
20160317 lagom sf scala20160317 lagom sf scala
20160317 lagom sf scalashinolajla
 
Effective Akka v2
Effective Akka v2Effective Akka v2
Effective Akka v2shinolajla
 
20150411 mutability matrix of pain scala
20150411 mutability matrix of pain scala20150411 mutability matrix of pain scala
20150411 mutability matrix of pain scalashinolajla
 
Reactive applications tools of the trade huff po
Reactive applications   tools of the trade huff poReactive applications   tools of the trade huff po
Reactive applications tools of the trade huff poshinolajla
 
20140228 fp and_performance
20140228 fp and_performance20140228 fp and_performance
20140228 fp and_performanceshinolajla
 
Real world akka recepies v3
Real world akka recepies v3Real world akka recepies v3
Real world akka recepies v3shinolajla
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scalashinolajla
 

Más de shinolajla (16)

20180416 reactive is_a_product_rs
20180416 reactive is_a_product_rs20180416 reactive is_a_product_rs
20180416 reactive is_a_product_rs
 
20180416 reactive is_a_product
20180416 reactive is_a_product20180416 reactive is_a_product
20180416 reactive is_a_product
 
20161027 scala io_keynote
20161027 scala io_keynote20161027 scala io_keynote
20161027 scala io_keynote
 
20160609 nike techtalks reactive applications tools of the trade
20160609 nike techtalks reactive applications   tools of the trade20160609 nike techtalks reactive applications   tools of the trade
20160609 nike techtalks reactive applications tools of the trade
 
20160524 ibm fast data meetup
20160524 ibm fast data meetup20160524 ibm fast data meetup
20160524 ibm fast data meetup
 
20160520 The Future of Services
20160520 The Future of Services20160520 The Future of Services
20160520 The Future of Services
 
20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdas20160520 what youneedtoknowaboutlambdas
20160520 what youneedtoknowaboutlambdas
 
20160317 lagom sf scala
20160317 lagom sf scala20160317 lagom sf scala
20160317 lagom sf scala
 
Effective Akka v2
Effective Akka v2Effective Akka v2
Effective Akka v2
 
20150411 mutability matrix of pain scala
20150411 mutability matrix of pain scala20150411 mutability matrix of pain scala
20150411 mutability matrix of pain scala
 
Reactive applications tools of the trade huff po
Reactive applications   tools of the trade huff poReactive applications   tools of the trade huff po
Reactive applications tools of the trade huff po
 
20140228 fp and_performance
20140228 fp and_performance20140228 fp and_performance
20140228 fp and_performance
 
Cpu Caches
Cpu CachesCpu Caches
Cpu Caches
 
Real world akka recepies v3
Real world akka recepies v3Real world akka recepies v3
Real world akka recepies v3
 
Taxonomy of Scala
Taxonomy of ScalaTaxonomy of Scala
Taxonomy of Scala
 
CPU Caches
CPU CachesCPU Caches
CPU Caches
 

Último

Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 

Último (20)

Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 

Effective Actors

  • 1. Effective  Actors Jamie  Allen Friday, January 11, 13
  • 2. Who  Am  I? •Consultant  at  Typesafe •Actor  &  Scala  developer  since  2009 jamie.allen@typesafe.com @jamie_allen Friday, January 11, 13
  • 3. Effective  Actors •Best  practices  based  on  several  years  of  actor   development •Helpful  hints  for  reasoning  about  actors  at  runtime @jamie_allen Friday, January 11, 13
  • 4. Actors •Concurrent,   A lightweight   processes  that   communicate   B C through   asynchronous   D message  passing •Isolation  of  state,  no   E F G internal  concurrency @jamie_allen Friday, January 11, 13
  • 5. Akka  Actors class Pinger extends Actor { def receive = { case _ => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case _ => println("Ponging!"); sender ! "Pong!" } } object PingPong extends App { val system = ActorSystem() val pinger = system.actorOf(Props[Pinger]) val ponger = system.actorOf(Props[Ponger]) pinger.tell("Ping!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 6. Akka  Actors class Pinger extends Actor { def receive = { case _ => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case _ => println("Ponging!"); sender ! "Pong!" } } object PingPong extends App { val system = ActorSystem() val pinger = system.actorOf(Props[Pinger]) val ponger = system.actorOf(Props[Ponger]) pinger.tell("Ping!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 7. Akka  Actors class Pinger extends Actor { def receive = { case _ => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case _ => println("Ponging!"); sender ! "Pong!" } } object PingPong extends App { val system = ActorSystem() val pinger = system.actorOf(Props[Pinger]) val ponger = system.actorOf(Props[Ponger]) pinger.tell("Ping!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 8. Akka  Actors class Pinger extends Actor { def receive = { case _ => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case _ => println("Ponging!"); sender ! "Pong!" } } object PingPong extends App { val system = ActorSystem() val pinger = system.actorOf(Props[Pinger]) val ponger = system.actorOf(Props[Ponger]) pinger.tell("Ping!", ponger) Thread.sleep(1000) system.shutdown } Overriding the “sender” @jamie_allen Friday, January 11, 13
  • 9. Supervisor  Hierarchies A •Specifies  handling   B C mechanisms  for   groupings  of  actors   in  parent/child   D relationship E F G @jamie_allen Friday, January 11, 13
  • 10. Akka  Supervisors class MySupervisor extends Actor { override val supervisorStrategy = OneForOneStrategy() { case ae: ArithmeticException => Resume case np: NullPointerException => Restart } context.actorOf(Props[MyActor]) } @jamie_allen Friday, January 11, 13
  • 11. Akka  Supervisors class MySupervisor extends Actor { override val supervisorStrategy = OneForOneStrategy() { case ae: ArithmeticException => Resume case np: NullPointerException => Restart } context.actorOf(Props[MyActor]) } @jamie_allen Friday, January 11, 13
  • 12. Akka  Supervisors class MySupervisor extends Actor { override val supervisorStrategy = OneForOneStrategy() { case ae: ArithmeticException => Resume case np: NullPointerException => Restart } context.actorOf(Props[MyActor]) } Note the “context” @jamie_allen Friday, January 11, 13
  • 13. Domain  Supervision •Each  supervisor  manages  a  grouping  of  types  in   a  domain •Actors  persist  to  represent  existence  of   instances  and  contain  their  own  state •Actors  constantly  resolve  the  world  as  it  should   be  against  the  world  as  it  is @jamie_allen Friday, January 11, 13
  • 14. Worker  Supervision •Supervisors  should  hold  all  critical  data •Workers  should  receive  data  for  tasks  in   messages •Workers  being  supervised  should  perform   dangerous  tasks •Supervisor  should  know  how  to  handle  failures   in  workers  in  order  to  retry  appropriately @jamie_allen Friday, January 11, 13
  • 15. Parallelism •Easily  scale  a  task  by   A creating  multiple   instances  of  an  actor   and  applying  work   B C using  various   strategies D •Order  is  not   guaranteed,  nor   E F G should  it  be @jamie_allen Friday, January 11, 13
  • 16. Akka  Routing class MyActor extends Actor { def receive = { case x => println(x) } } object Parallelizer extends App { val system = ActorSystem() val router: ActorRef = system.actorOf(Props[MyActor]. withRouter(RoundRobinRouter(nrOfInstances = 5))) for (i <- 1 to 10) router ! i } @jamie_allen Friday, January 11, 13
  • 17. Akka  Routing class MyActor extends Actor { def receive = { case x => println(x) } } object Parallelizer extends App { val system = ActorSystem() val router: ActorRef = system.actorOf(Props[MyActor]. withRouter(RoundRobinRouter(nrOfInstances = 5))) for (i <- 1 to 10) router ! i } @jamie_allen Friday, January 11, 13
  • 18. Akka  Routing class MyActor extends Actor { def receive = { case x => println(x) } } object Parallelizer extends App { val system = ActorSystem() val router: ActorRef = system.actorOf(Props[MyActor]. withRouter(RoundRobinRouter(nrOfInstances = 5))) for (i <- 1 to 10) router ! i } Should be configured externally @jamie_allen Friday, January 11, 13
  • 19. Akka  Routing class MyActor extends Actor { def receive = { case x => println(x) } } object Parallelizer extends App { val system = ActorSystem() val router: ActorRef = system.actorOf(Props[MyActor]. withRouter(RoundRobinRouter(nrOfInstances = 5))) for (i <- 1 to 10) router ! i } @jamie_allen Friday, January 11, 13
  • 20. RULE: Actors Should Only Do One Thing @jamie_allen Friday, January 11, 13
  • 21. Single  Responsibility  Principle •Do  not  conflate  responsibilities  in  actors •Becomes  hard  to  define  the  boundaries  of   responsibility •Supervision  becomes  more  difficult  as  you   handle  more  possibilities •Debugging  becomes  very  difficult @jamie_allen Friday, January 11, 13
  • 22. Supervision •Every  non-­‐leaf  node  is  technically  a  supervisor •Create  explicit  supervisors  under  each  node  for   each  type  of  child  to  be  managed @jamie_allen Friday, January 11, 13
  • 23. Conflated  Supervision C1 C2 Customers Accounts & Ac1 Ac2 D1 D2 D3 Devices A1 A2 A3 A4 Applications @jamie_allen Friday, January 11, 13
  • 24. Explicit  Supervision C1 C2 Customers DS Accounts & AS Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allen Friday, January 11, 13
  • 25. Keep  the  Error  Kernel  Simple •Limit  the  number  of  supervisors  you  create  at   this  level •Helps  with  fault  tolerance  and  explicit  handling   of  errors  through  the  hierarchy •Akka  uses  synchronous  messaging  to  create   top-­‐level  actors @jamie_allen Friday, January 11, 13
  • 26. Use  Failure  Zones •Multiple  isolated  zones  with  their  own   resources  (thread  pools,  etc) •Prevents  starvation  of  actors •Prevents  issues  in  one  branch  from  affecting   another @jamie_allen Friday, January 11, 13
  • 27. Failure  Zones C1 C2 Customers AS DS Accounts & Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allen Friday, January 11, 13
  • 28. Failure  Zones C1 C2 Customers AS DS Accounts & Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allen Friday, January 11, 13
  • 29. Takeaway •Isolation  of  groups  of  actors  limits  the  effects   of  failure •For  reasonably  complex  actor  systems,  shallow   trees  are  a  smell  test •Actors  are  cheap  -­‐  use  them @jamie_allen Friday, January 11, 13
  • 30. RULE: Block Only When and Where You Must @jamie_allen Friday, January 11, 13
  • 31. Consequences  of  Blocking •Eventually  results  in  actor  starvation  as  thread   pool  dries  up •Horrible  performance •Massive  waste  of  system  resources @jamie_allen Friday, January 11, 13
  • 32. Futures class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]) def receive = { case _ => worker ? (1 to 100) map (x => println("Got value: %d".format(x))) } } object Bootstrapper extends App { val system = ActorSystem() val delegator = system.actorOf(Props[Delegator]) delegator ! "Start" Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 33. Futures class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]) def receive = { case _ => worker ? (1 to 100) map (x => println("Got value: %d".format(x))) } } object Bootstrapper extends App { val system = ActorSystem() val delegator = system.actorOf(Props[Delegator]) delegator ! "Start" Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 34. Futures class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]) def receive = { case _ => worker ? (1 to 100) map (x => println("Got value: %d".format(x))) } } object Bootstrapper extends App { val system = ActorSystem() val delegator = system.actorOf(Props[Delegator]) delegator ! "Start" Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 35. Futures class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]) def receive = { case _ => worker ? (1 to 100) map (x => println("Got value: %d".format(x))) } } object Bootstrapper extends App { val system = ActorSystem() val delegator = system.actorOf(Props[Delegator]) delegator ! "Start" Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 36. Futures class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]) def receive = { case _ => worker ? (1 to 100) map (x => println("Got value: %d".format(x))) } } object Bootstrapper extends App { val system = ActorSystem() val delegator = system.actorOf(Props[Delegator]) delegator ! "Start" Thread.sleep(1000) system.shutdown } @jamie_allen Friday, January 11, 13
  • 37. Sequential  Futures val r: Future[Int] = for { a <- (service1 ? GetResult).mapTo[Int] b <- (service2 ? GetResult(a)).mapTo[Int] } yield a * b @jamie_allen Friday, January 11, 13
  • 38. Sequential  Futures Type Safety val r: Future[Int] = for { a <- (service1 ? GetResult).mapTo[Int] b <- (service2 ? GetResult(a)).mapTo[Int] } yield a * b @jamie_allen Friday, January 11, 13
  • 39. Parallel  Futures First way: Define futures first val f1: Future[Int] = service1 ? GetResult val f2: Future[Int] = service2 ? GetResult val r: Future[Int] = for { a <- f1 b <- f2 } yield a * b @jamie_allen Friday, January 11, 13
  • 40. Parallel  Futures Second way: Define in one line of for comprehension val r: Future[Int] = for { (a: Int, b: Int) <- (service1 ? GetResult) zip (service2 ? GetResult) } yield a * b Note the “zip” @jamie_allen Friday, January 11, 13
  • 41. Blocking •An  example  is  database  access •Use  a  specialized  actor  with  its  own  resources •Pass  messages  to  other  actors  to  handle  the   result •Akka  provides  “Managed  Blocking”  to  limit  the   number  of  blocking  operations  taking  place  in   actors  at  one  time @jamie_allen Friday, January 11, 13
  • 42. Akka  Dispatcher class Worker extends Actor { def receive = { case s: Seq[Int] => sender ! s.reduce(_ + _) } } class Delegator extends Actor { implicit val timeout: Timeout = 2 seconds val worker = context.actorOf(Props[Worker]). withDispatcher(“my-dispatcher”) Failure def receive = { case _ => Zone blocking { val futResult = worker ? (1 to 100) val result = Await.result(futResult, 2 seconds) } } } @jamie_allen Friday, January 11, 13
  • 43. Push,  Not  Pull •Start  with  no  guarantees  about  delivery •Add  guarantees  only  where  you  need  them •Retry  until  you  get  the  answer  you  expect •Switch  your  actor  to  a  "nominal"  state  at  that   point @jamie_allen Friday, January 11, 13
  • 44. Takeaway •Find  ways  to  ensure  that  your  actors  remain   asynchronous  and  non-­‐blocking •Avoid  making  your  actors  wait  for  anything   while  handling  a  message @jamie_allen Friday, January 11, 13
  • 45. RULE: Do Not Optimize Prematurely @jamie_allen Friday, January 11, 13
  • 46. Start  Simple •Make  Donald  Knuth  happy •Start  with  a  simple  configuration  and  profile •Do  not  parallelize  until  you  know  you  need  to   and  where @jamie_allen Friday, January 11, 13
  • 47. Initial  Focus •Deterministic •Declarative •Immutable •Start  with  functional  programming  and  go   from  there @jamie_allen Friday, January 11, 13
  • 48. Advice  From  Jonas  Bonér •Layer  in  complexity •Add  indeterminism •Add  mutability  in  hot  spots   (CAS  and  STM) •Add  explicit  locking  and   threads  as  a  last  resort Photo courtesy of Brian Clapper, NE Scala 2011 @jamie_allen Friday, January 11, 13
  • 49. Prepare  for  Race  Conditions •Write  actor  code  to  be  agnostic  of  time  and   order •Actors  should  only  care  about  now,  not  that   something  happened  before  it •Actors  can  "become"  or  represent  state   machines  to  represent  transitions @jamie_allen Friday, January 11, 13
  • 50. Beware  the  Thundering  Herd •Actor  systems  can  be  overwhelmed  by  "storms"  of   messages  flying  about •Do  not  pass  generic  messages  that  apply  to  many   actors •Dampen  actor  messages  if  the  exact  same  message  is   being  handled  repeatedly  within  a  certain  timeframe •Tune  your  dispatchers  and  mailboxes  via  back-­‐off   policies  and  queue  sizes •Akka  now  has  Circuit  Breakers @jamie_allen Friday, January 11, 13
  • 51. Takeaway •Start  by  thinking  in  terms  of  an  implementation   that  is  deterministic  and  not  actor  based •Layer  in  complexity  as  you  go @jamie_allen Friday, January 11, 13
  • 52. RULE: Be Explicit In Your Intent @jamie_allen Friday, January 11, 13
  • 53. Name  Your  Actors •Allows  for  external  configuration •Allows  for  lookup •Better  semantic  logging val system = ActorSystem("pingpong") val pinger = system.actorOf(Props[Pinger], "pinger") val ponger = system.actorOf(Props[Ponger], "ponger") @jamie_allen Friday, January 11, 13
  • 54. Create  Specialized  Messages •Non-­‐specific  messages  about  general  events   are  dangerous AccountsUpdated •Can  result  in  "event  storms"  as  all  actors  react  to   them •Use  specific  messages  forwarded  to  actors  for   handling AccountDeviceAdded(acctNum, deviceNum) @jamie_allen Friday, January 11, 13
  • 55. Create  Specialized  Exceptions •Don't  use  java.lang.Exception  to  represent   failure  in  an  actor •Specific  exceptions  can  be  handled  explicitly •State  can  be  transferred  between  actor   incarnations  in  Akka  (if  need  be) @jamie_allen Friday, January 11, 13
  • 56. Takeaway •Be  specific  in  everything  you  do •Makes  everything  that  occurs  in  your  actor   system  more  clear  to  other  developers   maintaining  the  code •Makes  everything  more  clear  in  production @jamie_allen Friday, January 11, 13
  • 57. RULE: Do Not Expose Your Actors @jamie_allen Friday, January 11, 13
  • 58. No  Direct  References •Actors  die •Doesn't  prevent  someone  from  calling  into  an   actor  with  another  thread •Akka  solves  this  with  the  ActorRef  abstraction •Erlang  solves  this  with  PIDs @jamie_allen Friday, January 11, 13
  • 59. Never  Publish  “this” •Don't  send  it  anywhere •Don't  register  it  anywhere •Particularly  with  future  callbacks •Publish  “self”  instead,  which  is  an  ActorRef •Avoid  closing  over  "sender"  in  Akka,  it  will   change  with  the  next  message @jamie_allen Friday, January 11, 13
  • 60. Use  Immutable  Messages •Enforces  which  actor  owns  the  data •If  mutable  state  can  escape,  what  is  the  point   of  using  an  actor? @jamie_allen Friday, January 11, 13
  • 61. Pass  Copies  of  Mutable  Data •Mutable  data  in  actors  is  fine •But  data  can  escape  your  scope •Copy  the  data  and  pass  that,  as  Erlang  does   (COW) •Akka  has  STM  references @jamie_allen Friday, January 11, 13
  • 62. Avoid  Sending  Behavior •Unless  using  Agents,  of  course •Closures  make  this  possible  (and  easy) •Also  makes  it  easy  for  state  to  escape @jamie_allen Friday, January 11, 13
  • 63. Takeaway •Keep  everything  about  an  actor  internal  to  that   actor •Be  vary  wary  of  data  passed  in  closures  to   anyone  else @jamie_allen Friday, January 11, 13
  • 64. RULE: Make Debugging Easy On Yourself @jamie_allen Friday, January 11, 13
  • 65. Externalize  Business  Logic •Consider  using  external  functions  to   encapsulate  complex  business  logic •Easier  to  unit  test  outside  of  actor  context •Not  a  rule  of  thumb,  but  something  to  consider   as  complexity  increases •Not  as  big  of  an  issue  with  Akka's  TestKit @jamie_allen Friday, January 11, 13
  • 66. Use  Semantically  Useful  Logging •Trace-­‐level  logs  should  have  output  that  you   can  read  easily •Use  line-­‐breaks  and  indentation •Both  Akka  and  Erlang  support  hooking  in   multiple  listeners  to  the  event  log  stream @jamie_allen Friday, January 11, 13
  • 67. Unique  IDs  for  Messages •Allows  you  to  track  message  flow •When  you  find  a  problem,  get  the  ID  of  the   message  that  led  to  it •Use  the  ID  to  grep  your  logs  and  display  output   just  for  that  message  flow •Akka  ensures  ordering  on  a  per  actor  basis,  also   in  logging @jamie_allen Friday, January 11, 13
  • 68. Monitor  Everything •Do  it  from  the  start •Use  tools  like  JMX  MBeans  to  visualize  actor   realization •The  Typesafe  Console  is  a  great  tool  to  visualize   actor  systems,  doesn't  require  you  to  do   anything  up  front •Visual  representations  of  actor  systems  at   runtime  are  invaluable @jamie_allen Friday, January 11, 13
  • 69. Typesafe  Console @jamie_allen Friday, January 11, 13
  • 70. Takeaway •Build  your  actor  system  to  be  maintainable   from  the  outset •Utilize  all  of  the  tools  at  your  disposal @jamie_allen Friday, January 11, 13
  • 71. Thank  You! •Some  content  provided  by  members  of  the   Typesafe  team,  including: •Jonas  Bonér •Viktor  Klang •Roland  Kuhn •Havoc  Pennington @jamie_allen Friday, January 11, 13

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n