Effective	  Actors                             Jamie	  AllenSaturday, March 2, 13
Who	  Am	  I?         •Consultant	  at	  Typesafe         •Actor	  &	  Scala	  developer	  since	  2009                   ...
Effective	  Actors         •Best	  practices	  based	  on	  several	  years	  of	  actor	                  development     ...
Actors            •Concurrent,	                                 A                    lightweight	                      pro...
Akka	  Actors        class Pinger extends Actor {          def receive = {            case "Pong" => println("Pinging!"); ...
Akka	  Actors        class Pinger extends Actor {          def receive = {            case "Pong" => println("Pinging!"); ...
Akka	  Actors        class Pinger extends Actor {          def receive = {            case "Pong" => println("Pinging!"); ...
Akka	  Actors        class Pinger extends Actor {          def receive = {            case "Pong" => println("Pinging!"); ...
Supervisor	  Hierarchies                                                            A            •Specifies	  handling	    ...
Akka	  Supervisors        class MySupervisor extends Actor {          override val supervisorStrategy =            OneForO...
Akka	  Supervisors        class MySupervisor extends Actor {          override val supervisorStrategy =            OneForO...
Akka	  Supervisors        class MySupervisor extends Actor {          override val supervisorStrategy =            OneForO...
Domain	  Supervision         •Each	  supervisor	  manages	  a	  grouping	  of	  types	  in	                  a	  domain   ...
Worker	  Supervision         •Supervisors	  should	  hold	  all	  critical	  data         •Workers	  should	  receive	  da...
Parallelism            •Easily	  scale	  a	  task	  by	                A                    creating	  multiple	          ...
Akka	  Routing        class MyActor extends Actor {          def receive = { case x => println(x) }        }        object...
Akka	  Routing        class MyActor extends Actor {          def receive = { case x => println(x) }        }        object...
Akka	  Routing        class MyActor extends Actor {          def receive = { case x => println(x) }        }        object...
Akka	  Routing        class MyActor extends Actor {          def receive = { case x => println(x) }        }        object...
RULE:              Actors Should Only Do One Thing                                          @jamie_allenアクターは1つの事に特化することSa...
Single	  Responsibility	  Principle         •Do	  not	  conflate	  responsibilities	  in	  actors         •Becomes	  hard	 ...
Supervision         •Every	  non-­‐leaf	  node	  is	  technically	  a	  supervisor         •Create	  explicit	  supervisor...
Conflated	  Supervision          C1                               C2                             Customers                 ...
Explicit	  Supervision                C1                              C2                                  Customers       ...
Keep	  the	  Error	  Kernel	  Simple         •Limit	  the	  number	  of	  supervisors	  you	  create	  at	                ...
Use	  Failure	  Zones         •Multiple	  isolated	  zones	  with	  their	  own	                  resources	  (thread	  po...
Failure	  Zones                C1                         C2                             Customers                        ...
Failure	  Zones                C1                         C2                             Customers                        ...
Takeaway         •Isolation	  of	  groups	  of	  actors	  limits	  the	  effects	                  of	  failure         •Fo...
RULE:     Block Only When and Where You Must                                  @jamie_allen必要な時に、必要な場所のみでブロックすることSaturday, ...
Consequences	  of	  Blocking         •Eventually	  results	  in	  actor	  starvation	  as	  thread	                  pool	...
Futures        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.reduce(_ + ...
Futures        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.reduce(_ + ...
Futures        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.reduce(_ + ...
Futures        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.reduce(_ + ...
Futures        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.reduce(_ + ...
Sequential	  Futures        val r: Future[Int] = for {          a <- (service1 ? GetResult).mapTo[Int]          b <- (serv...
Sequential	  Futures                                 Type Safety        val r: Future[Int] = for {          a <- (service1...
Parallel	  Futures        First way: Define futures first        val f1: Future[Int] = service1 ? GetResult        val f2: F...
Parallel	  Futures     Second way: Define in one line of for comprehension      val r: Future[Int] = for {        (a: Int, ...
Blocking         •An	  example	  is	  database	  access         •Use	  a	  specialized	  actor	  with	  its	  own	  resour...
Akka	  Dispatcher        class Worker extends Actor {          def receive = {            case s: Seq[Int] => sender ! s.r...
Push,	  Not	  Pull         •Start	  with	  no	  guarantees	  about	  delivery         •Add	  guarantees	  only	  where	  y...
Takeaway         •Find	  ways	  to	  ensure	  that	  your	  actors	  remain	                  asynchronous	  and	  non-­‐b...
RULE:                        Do Not Optimize Prematurely                                                  @jamie_allen早すぎる...
Start	  Simple         •Make	  Donald	  Knuth	  happy         •Start	  with	  a	  simple	  configuration	  and	  profile    ...
Initial	  Focus         •Deterministic         •Declarative         •Immutable         •Start	  with	  functional	  progra...
Advice	  From	  Jonas	  Bonér         •Layer	  in	  complexity         •Add	  indeterminism         •Add	  mutability	  in...
Prepare	  for	  Race	  Conditions         •Write	  actor	  code	  to	  be	  agnostic	  of	  time	  and	                  o...
Beware	  the	  Thundering	  Herd         •Actor	  systems	  can	  be	  overwhelmed	  by	  "storms"	  of	                  ...
Takeaway         •Start	  by	  thinking	  in	  terms	  of	  an	  implementation	                  that	  is	  deterministi...
RULE:                        Be Explicit In Your Intent                                                     @jamie_allen意図...
Name	  Your	  Actors         •Allows	  for	  external	  configuration         •Allows	  for	  lookup         •Better	  sema...
Create	  Specialized	  Messages         •Non-­‐specific	  messages	  about	  general	  events	                  are	  dange...
Create	  Specialized	  Exceptions         •Dont	  use	  java.lang.Exception	  to	  represent	                  failure	  i...
Takeaway         •Be	  specific	  in	  everything	  you	  do         •Makes	  everything	  that	  occurs	  in	  your	  acto...
RULE:                        Do Not Expose Your Actors                                                    @jamie_allenアクター...
No	  Direct	  References         •Actors	  die         •Doesnt	  prevent	  someone	  from	  calling	  into	  an	          ...
Never	  Publish	  “this”         •Dont	  send	  it	  anywhere         •Dont	  register	  it	  anywhere         •Particular...
Use	  Immutable	  Messages         •Enforces	  which	  actor	  owns	  the	  data         •If	  mutable	  state	  can	  esc...
Pass	  Copies	  of	  Mutable	  Data         •Mutable	  data	  in	  actors	  is	  fine         •But	  data	  can	  escape	  ...
Avoid	  Sending	  Behavior         •Unless	  using	  Agents,	  of	  course         •Closures	  make	  this	  possible	  (a...
Takeaway         •Keep	  everything	  about	  an	  actor	  internal	  to	  that	                  actor         •Be	  vary...
RULE:                Make Debugging Easy On Yourself                                            @jamie_allenデバッギングが簡単にできるよ...
Externalize	  Business	  Logic         •Consider	  using	  external	  functions	  to	                  encapsulate	  compl...
Use	  Semantically	  Useful	  Logging         •Trace-­‐level	  logs	  should	  have	  output	  that	  you	                ...
Unique	  IDs	  for	  Messages         •Allows	  you	  to	  track	  message	  flow         •When	  you	  find	  a	  problem,	...
Monitor	  Everything         •Do	  it	  from	  the	  start         •Use	  tools	  like	  JMX	  MBeans	  to	  visualize	  a...
Typesafe	  Console                                              @jamie_allenSaturday, March 2, 13
Takeaway         •Build	  your	  actor	  system	  to	  be	  maintainable	                  from	  the	  outset         •Ut...
Thank	  You!         •Some	  content	  provided	  by	  members	  of	  the	                  Typesafe	  team,	  including: ...
Upcoming SlideShare
Loading in …5
×

Effective actors japanesesub

2,849 views

Published on

Published in: Technology
0 Comments
20 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,849
On SlideShare
0
From Embeds
0
Number of Embeds
271
Actions
Shares
0
Downloads
45
Comments
0
Likes
20
Embeds 0
No embeds

No notes for slide

Effective actors japanesesub

  1. 1. Effective  Actors Jamie  AllenSaturday, March 2, 13
  2. 2. Who  Am  I? •Consultant  at  Typesafe •Actor  &  Scala  developer  since  2009 jamie.allen@typesafe.com @jamie_allenTypesafe 社でコンサルタントしていますSaturday, March 2, 13
  3. 3. Effective  Actors •Best  practices  based  on  several  years  of  actor   development •Helpful  hints  for  reasoning  about  actors  at  runtime @jamie_allen何年かの開発に基づいたベスト・プラクティスとヒントSaturday, March 2, 13
  4. 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状態の隔離Saturday, March 2, 13
  5. 5. Akka  Actors class Pinger extends Actor { def receive = { case "Pong" => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case "Ping" => 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("Pong!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allenSaturday, March 2, 13
  6. 6. Akka  Actors class Pinger extends Actor { def receive = { case "Pong" => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case "Ping" => 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("Pong!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allenSaturday, March 2, 13
  7. 7. Akka  Actors class Pinger extends Actor { def receive = { case "Pong" => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case "Ping" => 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("Pong!", ponger) Thread.sleep(1000) system.shutdown } @jamie_allenSaturday, March 2, 13
  8. 8. Akka  Actors class Pinger extends Actor { def receive = { case "Pong" => println("Pinging!"); sender ! "Ping!" } } class Ponger extends Actor { def receive = { case "Ping" => 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("Pong!", ponger) Thread.sleep(1000) system.shutdown } Overriding the “sender” @jamie_allenSaturday, March 2, 13
  9. 9. Supervisor  Hierarchies A •Specifies  handling   B C mechanisms  for   groupings  of  actors   in  parent/child   D relationship E F G @jamie_allenSupervisor はアクター階層の処理を定義するSaturday, March 2, 13
  10. 10. Akka  Supervisors class MySupervisor extends Actor { override val supervisorStrategy = OneForOneStrategy() { case ae: ArithmeticException => Resume case np: NullPointerException => Restart } context.actorOf(Props[MyActor]) } @jamie_allenSaturday, March 2, 13
  11. 11. Akka  Supervisors class MySupervisor extends Actor { override val supervisorStrategy = OneForOneStrategy() { case ae: ArithmeticException => Resume case np: NullPointerException => Restart } context.actorOf(Props[MyActor]) } @jamie_allenSaturday, March 2, 13
  12. 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_allenSaturday, March 2, 13
  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_allenSupervisor 階層を利用しドメインをモデルするSaturday, March 2, 13
  14. 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  appropriatelySupervisor がデータを保持し、メッセージでワーカーに渡す @jamie_allenワーカーは死んでも構わないSaturday, March 2, 13
  15. 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複数のアクターを作成することでタスクをスケールSaturday, March 2, 13
  16. 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_allenSaturday, March 2, 13
  17. 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_allenSaturday, March 2, 13
  18. 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_allenSaturday, March 2, 13
  19. 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_allenSaturday, March 2, 13
  20. 20. RULE: Actors Should Only Do One Thing @jamie_allenアクターは1つの事に特化することSaturday, March 2, 13
  21. 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単一責任の原則: なんでもかんでも手を出さないSaturday, March 2, 13
  22. 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アクターの種類ごとに Supervisor を分けることSaturday, March 2, 13
  23. 23. Conflated  Supervision C1 C2 Customers Accounts & Ac1 Ac2 D1 D2 D3 Devices A1 A2 A3 A4 Applications @jamie_allen混ざってる SupervisorSaturday, March 2, 13
  24. 24. Explicit  Supervision C1 C2 Customers DS Accounts & AS Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allen明示的な SupervisorSaturday, March 2, 13
  25. 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_allenError Kernel はシンプルにSaturday, March 2, 13
  26. 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_allenFailure Zone を使ってリソースを隔離するSaturday, March 2, 13
  27. 27. Failure  Zones C1 C2 Customers AS DS Accounts & Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allenSaturday, March 2, 13
  28. 28. Failure  Zones C1 C2 Customers AS DS Accounts & Devices Ac1 Ac2 D1 D2 D3 A1 A2 A3 A4 Applications @jamie_allenSaturday, March 2, 13
  29. 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アクターのグループを隔離することで障害の影響を抑えるSaturday, March 2, 13
  30. 30. RULE: Block Only When and Where You Must @jamie_allen必要な時に、必要な場所のみでブロックすることSaturday, March 2, 13
  31. 31. Consequences  of  Blocking •Eventually  results  in  actor  starvation  as  thread   pool  dries  up •Horrible  performance •Massive  waste  of  system  resourcesブロッキングの行く末: 無くなるスレッド、飢えるアクター、 @jamie_allen落ちる性能Saturday, March 2, 13
  32. 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 "Start" => 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_allenSaturday, March 2, 13
  33. 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 "Start" => 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_allenSaturday, March 2, 13
  34. 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 "Start" => 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_allenSaturday, March 2, 13
  35. 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 "Start" => 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_allenSaturday, March 2, 13
  36. 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 "Start" => 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_allenSaturday, March 2, 13
  37. 37. Sequential  Futures val r: Future[Int] = for { a <- (service1 ? GetResult).mapTo[Int] b <- (service2 ? GetResult(a)).mapTo[Int] } yield a * b @jamie_allen順次 FutureSaturday, March 2, 13
  38. 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順次 FutureSaturday, March 2, 13
  39. 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並列 Future 方法1: 事前に Future を定義Saturday, March 2, 13
  40. 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並列 Future 方法2: zip を使って 1行で定義Saturday, March 2, 13
  41. 41. Blocking •An  example  is  database  access •Use  a  specialized  actor  with  its  own  resources •Pass  messages  to  other  actors  to  handle  the   result •Scala  provides  “Managed  Blocking”  to  limit  the   number  of  blocking  operations  taking  place  in   actors  at  one  time @jamie_allenブロッキング専門のアクターを作るSaturday, March 2, 13
  42. 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_allenSaturday, March 2, 13
  43. 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配達時間はまず保証無しから始めるSaturday, March 2, 13
  44. 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アクターが非同期で非ブロッキングであるように努めることSaturday, March 2, 13
  45. 45. RULE: Do Not Optimize Prematurely @jamie_allen早すぎる最適化はダメSaturday, March 2, 13
  46. 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プロファイルも取らずに並列化しないことSaturday, March 2, 13
  47. 47. Initial  Focus •Deterministic •Declarative •Immutable •Start  with  functional  programming  and  go   from  there @jamie_allenまずは決定的、宣言型、不変など関数型の基本からSaturday, March 2, 13
  48. 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段階的に複雑さを導入する: 1. 非決定性 2. 可変性 @jamie_allen3. スレッドと明示的なロックは最終手段Saturday, March 2, 13
  49. 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アクターは時間と順序に無関心であるべきSaturday, March 2, 13
  50. 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複数のアクターに作用する汎用メッセージは避けるSaturday, March 2, 13
  51. 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まずはアクターを使わない決定的な実装からSaturday, March 2, 13
  52. 52. RULE: Be Explicit In Your Intent @jamie_allen意図をハッキリさせることSaturday, March 2, 13
  53. 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アクターには名前を付けることSaturday, March 2, 13
  54. 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専用メッセージを作る。汎用イベントは危険。Saturday, March 2, 13
  55. 55. Create  Specialized  Exceptions •Dont  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専用例外を作るSaturday, March 2, 13
  56. 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全てにおいて特定であること。本番環境でも役立つ。Saturday, March 2, 13
  57. 57. RULE: Do Not Expose Your Actors @jamie_allenアクターを公開しないことSaturday, March 2, 13
  58. 58. No  Direct  References •Actors  die •Doesnt  prevent  someone  from  calling  into  an   actor  with  another  thread •Akka  solves  this  with  the  ActorRef  abstraction •Erlang  solves  this  with  PIDs @jamie_allen絶対にアクターを直接参照してはいけないSaturday, March 2, 13
  59. 59. Never  Publish  “this” •Dont  send  it  anywhere •Dont  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絶対に this を返してはいけない。代わりに self を使う。Saturday, March 2, 13
  60. 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不変メッセージを使うことSaturday, March 2, 13
  61. 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可変データはコピーを送るSaturday, March 2, 13
  62. 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振る舞いを送ることは避けるSaturday, March 2, 13
  63. 63. Takeaway •Keep  everything  about  an  actor  internal  to  that   actor •Be  vary  wary  of  data  passed  in  closures  to   anyone  else @jamie_allenアクターの内部構造を外に見せないことSaturday, March 2, 13
  64. 64. RULE: Make Debugging Easy On Yourself @jamie_allenデバッギングが簡単にできるようにするSaturday, March 2, 13
  65. 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  Akkas  TestKit @jamie_allenビジネス・ロジックは外に書くSaturday, March 2, 13
  66. 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読んで意味のあるログを書くSaturday, March 2, 13
  67. 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メッセージにユニークIDをふるSaturday, March 2, 13
  68. 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,  doesnt  require  you  to  do   anything  up  front •Visual  representations  of  actor  systems  at   runtime  are  invaluable @jamie_allen全てを監視するSaturday, March 2, 13
  69. 69. Typesafe  Console @jamie_allenSaturday, March 2, 13
  70. 70. Takeaway •Build  your  actor  system  to  be  maintainable   from  the  outset •Utilize  all  of  the  tools  at  your  disposal @jamie_allenメンテが容易なアクターシステムを構築するSaturday, March 2, 13
  71. 71. Thank  You! •Some  content  provided  by  members  of  the   Typesafe  team,  including: •Jonas  Bonér •Viktor  Klang •Roland  Kuhn •Havoc  Pennington @jamie_allenご清聴ありがとうございましたSaturday, March 2, 13

×