Reactive Domain Driven Design - elsassjug

772 vues

Publié le

Si vous pensez que le Domain Driven Design c’est seulement pour Java EE et que le reactive programming rend le code illisible et prématurément optimisé, cette présentation va vous surprendre. Venez voir comment DDD + CQRS + EventSourcing se conjuguent parfaitement avec Akka pour construire des systèmes robustes dans un environnement concurrentiel.

Par Xavier Bucchiotty, consultant chez Xebia France

Publié dans : Logiciels
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
772
Sur SlideShare
0
Issues des intégrations
0
Intégrations
6
Actions
Partages
0
Téléchargements
8
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Reactive Domain Driven Design - elsassjug

  1. 1. Reactive Domain Driven Design • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  2. 2. The Objective • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  3. 3. The red squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  4. 4. Characters /Alliance /Red squadron /Empire / DeathStar • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  5. 5. Attack class Alliance{ val squadrons = Set[Squadron]; • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! def attack(empire){ ! val deathStar = empire.deathStar ! squadron.foreach(squadron => squadron.attack(deathStar) ) } }
  6. 6. Idle • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  7. 7. class Squadron{ var location = base; • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! def attack(){ travelTo(deathStar){ … this.location = deathStar … } ! } } Traveling
  8. 8. class Squadron{ val xwings = Set[Squadron]; • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! def attack(deathStar){ travelTo(deathStar) ! do{ xwings.foreach(_.attack(deathStar)) }while(deathStar.alive) ! } } Fighting
  9. 9. class XWing{ var healthPoints = 1 • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! def attack(deathStar){ ! deathStar.receiveTorpedoFrom(this) ! ! ! ! } } Fighting
  10. 10. class DeathStar{ var healthPoints = 100 • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! def receiveTorpedoFrom(sender){ healthPoints -= 1 if(senderWithoutTheForce){ sender.receiveTorpedoFrom(this) } } ! } Fighting
  11. 11. User Story As the Alliance ! I want to be informed of updates in state of my squadrons ! In order to command the retreat of a squadron if it remains only one XWing • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  12. 12. Tasks Notification from XWing to Squadron Notification from Squadron to Alliance Implements Squadron#retreat • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  13. 13. Notification from XWing to Squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 !!! def receiveTorpedoFrom(sender){ ! println(s”$this is dead”) } }
  14. 14. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val squadron = parent ! def receiveTorpedoFrom(sender){ squadron.remove(this) println(s”$this is dead”) } } Notification from XWing to Squadron
  15. 15. } Remember No bidirectional references • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val squadron = parent ! def receiveTorpedoFrom(sender){ squadron.remove(this) println(s”$this is dead”) } Notification from XWing to Squadron
  16. 16. Notification from XWing to Squadron } What would be • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val squadron = parent ! def receiveTorpedoFrom(sender){ squadron.remove(this) println(s”$this is dead”) } visibility of remove?
  17. 17. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! ! def receiveTorpedoFrom(sender){ println(s”$this is dead”) } ! } Notification from XWing to Squadron
  18. 18. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val life = Promise[Unit]() ! def receiveTorpedoFrom(sender){ life.success(null) println(s”$this is dead”) } ! def endOfLife = life.future } Notification from XWing to Squadron
  19. 19. Notification from XWing to Squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val life = Promise[Unit]() ! def receiveTorpedoFrom(sender){ life.success(null) println(s”$this is dead”) } ! def endOfLife = life.future } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= xwing ) ) ! }
  20. 20. Notification from XWing to Squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val life = Promise[Unit]() ! def receiveTorpedoFrom(sender){ life.success(null) println(s”$this is dead”) } ! def endOfLife = life.future } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= xwing ) ) ! } Loosely coupled
  21. 21. Notification from XWing to Squadron But we starts with asynchronous • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val life = Promise[Unit]() ! def receiveTorpedoFrom(sender){ life.success(null) println(s”$this is dead”) } ! def endOfLife = life.future } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing ) ) ! } Loosely coupled
  22. 22. Notification from XWing to Squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class XWing{ var healthPoints = 1 ! val life = Promise[Unit]() ! def receiveTorpedoFrom(sender){ life.success(null) println(s”$this is dead”) } ! def endOfLife = life.future } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= xwing ) ) ! }
  23. 23. Tasks Notification from XWing to Squadron Notification from Squadron to Alliance Implements Squadron#retreat • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  24. 24. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() ! !!!!!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing ) ) ! def alliance = ??? }
  25. 25. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() ! !!!!!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing ) ) ! def alliance = ??? } Remember again No bidirectional references
  26. 26. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() ! !!!!!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing ) ) !! }
  27. 27. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() squadrons.foreach(squadron => squadron.listener += { updatedSquadron => { if(updatedSquadron.currentSize < 2){ updatedSquadron.retreat() } } } ) !!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing listeners.foreach(l => l.apply(this) ) ) ) var listeners = List[Squadron => Unit] ! def currentSize = xwings.size ! def retreat = ??? }
  28. 28. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() squadrons.foreach(squadron => squadron.listener += { updatedSquadron => { if(updatedSquadron.currentSize < 2){ updatedSquadron.retreat() } } } ) !!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing listeners.foreach(l => l.apply(this) ) ) ) var listeners = List[Squadron => Unit] ! def currentSize = xwings.size ! def retreat = ??? } Will make the tests green
  29. 29. Notification from Squadron to Alliance • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Alliance{ val squadrons = Seq[Squadron]() squadrons.foreach(squadron => squadron.listener += { updatedSquadron => { if(updatedSquadron.currentSize < 2){ updatedSquadron.retreat() } } } ) !!!! } class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map(_ => xwings -= deadXWing listeners.foreach(l => l.apply(this) ) ) ) var listeners = List[Squadron => Unit] ! def currentSize = xwings.size ! def retreat = ??? }
  30. 30. Tasks Notification from Squadron to Alliance Implements Squadron#retreat • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  31. 31. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() ! def retreat() = ??? !!!!!! } Implements Squadron#retreat
  32. 32. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() ! def retreat() = { travelTo(base) } !!!!! } Implements Squadron#retreat
  33. 33. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() def retreat() = { travelTo(base) } !!!!! } Implements Squadron#retreat That does not stop XWings to fire
  34. 34. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var fighting = false def retreat() = { figthing = false travelTo(base) } ! def attack(deathStar){ travel(deathStar) fighting = true do { xwings.foreach(_.attack(deathStar)) } while (deathStar.alive && fighting) } } Implements Squadron#retreat Will make the tests green
  35. 35. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var fighting = false def retreat() = { figthing = false travelTo(base) } ! def attack(deathStar){ travel(deathStar) fighting = true do { xwings.foreach(_.attack(deathStar)) } while (deathStar.alive && fighting) } } Implements Squadron#retreat But wait we have a shared mutable state
  36. 36. User Story As the Alliance ! I want to display each modification in the status of my squadron ! In order to see evolution of the battle • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  37. 37. Tasks Get current status as String from a Squadron Notification at the end of travels • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  38. 38. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map { _ => !! } ) !!!!! } Notification at the end of travels
  39. 39. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() ! xwings.foreach(xwing => xwing.endOfLife.map { _ => notifyListeners() ! } ) ! def attack(deathStar: DeathStar){ ! travelTo(deathStar) notifyListeners() ! } ! def retreat(){ travelTo(base) notifyListeners() } } Notification at the end of travels Will make the tests green
  40. 40. Tasks Get current status as String from a Squadron Notification at the end of travels • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  41. 41. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() !! !!!!! } Get current status as String from a Squadron
  42. 42. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC class Squadron{ var xwings = Set[XWing]() ! status(“idle“) def attack(deathStar){ status(“traveling“) notifyListeners() ! travelTo(deathStar) status(“figthing“) notifyListeners() } ! … !! } Get current status as String from a Squadron That’s too much, there must be another way
  43. 43. Backlog Make the travel asynchronous so many squadrons can move at the same time Persist state of squadrons to spawn them on new VM if lost • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  44. 44. Domain Driven Design • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  45. 45. http://www.amazon.fr/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215 • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  46. 46. Technical core concepts Aggregate Bounded context • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  47. 47. Technical core concepts scalability code Aggregate Bounded context transaction • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  48. 48. code scalability • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  49. 49. code scalability • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Knight Knight
  50. 50. code scalability Implementation is focused on a bounded context of the whole domain • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Knight Knight
  51. 51. code scalability • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  52. 52. code scalability • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  53. 53. code scalability Aggregate hides implementation details • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  54. 54. code scalability Aggregate hides implementation details Implementation is focused on a bounded context of the whole domain • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  55. 55. Technical core concepts scalability code Aggregate Bounded context transaction • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  56. 56. transaction • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  57. 57. transaction • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  58. 58. transaction ? • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  59. 59. transaction Root entity ensures consistency of the whole aggregate at any time • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  60. 60. transaction ! can see 4 XWings • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  61. 61. transaction When the Alliance can see the changes? ! can see 3 XWings • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  62. 62. transaction ! can see 3 XWings From an external point of view, the aggregate is eventually consistent! • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  63. 63. transaction From an external point of view, the aggregate is eventually consistent! Root entity ensures consistency of the whole aggregate at any time • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  64. 64. Domain Driven Design • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  65. 65. CQRS Domain Driven Design ++ EventSourcing • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  66. 66. CQRS Command Query Responsibility Segregation Forget about POJOs and Java Beans getters/setters. Do semantical methods! You can model your domain twice! Once per usage. ! Command ≠ Query • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  67. 67. EventSourcing Forget about Hibernate and other ORMs. Persists meaningful past events. ! Command ≠ Event • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  68. 68. Functional EventSourcing x (Aggregate) (Actions) Events Decision Command State making Events x State (Aggregate) apply State (Aggregate) + • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  69. 69. Functional EventSourcing You don’t even need to persist complete aggregates x (Aggregate) (Actions) Events Decision Command State making Events x State (Aggregate) state ! apply State (Aggregate) + • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  70. 70. Functional EventSourcing x (Aggregate) Events Decision Command State making Events x State (Aggregate) apply State (Aggregate) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  71. 71. Functional EventSourcing source: @thinkbeforecoding x (Aggregate) Events Decision Command State making https://github.com/thinkbeforecoding/FsUno.Prod Events x State (Aggregate) ! apply State (Aggregate) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  72. 72. Command ≠ Query Command ≠ Event • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  73. 73. Event Actions Command • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  74. 74. Event Actions But where are the views? Command • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  75. 75. And the views? You can keep specific views inside aggregates. You’ll bother the root for minor subjects. Lost(red-1) Reporter • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  76. 76. And the views? You read events log and build ad-hoc views. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC ! In « real-time » or on demand. Listener Lost(red-1)
  77. 77. In DDD, aggregates and entities have unique IDs. So does the actors with paths and name In DDD, value object are everywhere and are immutable. So does case classes. Immutability help reasoning in concurrent world. In DDD, aggregates encapsulate states, so does actors • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  78. 78. Reactive Domain Driven Design • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  79. 79. Reactive • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  80. 80. http://www.reactivemanifesto.org/ • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  81. 81. http://www.reactivemanifesto.org/ asynchronous low coupling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  82. 82. scaling to workload http://www.reactivemanifesto.org/ • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  83. 83. http://www.reactivemanifesto.org/ sane error and failure handling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  84. 84. system always responds in bounded latency http://www.reactivemanifesto.org/ • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  85. 85. Tasks Let’s do a refactor with Akka • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  86. 86. Aggregate Red squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  87. 87. Characters /Alliance /Red squadron /Empire / DeathStar • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  88. 88. Actors /Alliance /Red squadron /Empire / DeathStar • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  89. 89. Functional EventSourcing x (Aggregate) Actions Events Decision Command State making + • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  90. 90. Messages Attack ( DeathStarPath , Squadron ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  91. 91. Messages Attack ( DeathStarPath , Squadron ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  92. 92. Idle • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  93. 93. Traveling Sent ( Squadron, Destination ) Travel ( Squadron, Destination ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  94. 94. Traveling Sent ( Squadron, Destination ) Travel ( Squadron, Destination ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  95. 95. Traveling Arrived ( Squadron, Destination ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  96. 96. Traveling Arrived ( Squadron, Destination ) Arrived ( Squadron, Destination ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  97. 97. Fighting Fire ( DeathStarPath ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  98. 98. Fighting Fire ( DeathStarPath ) Fire ( XWingPath ) Lost ( Squadron, XWing ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  99. 99. Messages Attack ( DeathStarPath , Squadron ) Arrived ( Squadron, Destination ) Fire ( DeathStarPath ) Travel ( Squadron, Destination ) Sent ( Squadron, Destination ) Arrived ( Squadron, Destination ) Lost ( Squadron, Destination ) • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Fire ( XWingPath )
  100. 100. Algebras Fire x Fighting Lost Fighting x Lost Fighting • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  101. 101. Algebras Akka killing feature Fire x Fighting Lost ! receive as Partial Function Fighting x Lost Fighting context.become() • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  102. 102. Algebras Think about functions validating inputs for some outputs Fire x Fighting Lost Fighting x Lost Fighting • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  103. 103. Algebras Finite State Machine Fire x Fighting Lost ! Fighting x Lost Fighting For The Win • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  104. 104. Algebras NOW THE CODE Fire x Fighting Lost Fighting x Lost Fighting • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  105. 105. akka-cluster akka-persistence http://www.reactivemanifesto.org/ akka-actor • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  106. 106. akka-actor Idle • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Attack
  107. 107. akka-actor Idle Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  108. 108. akka-actor Idle Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  109. 109. akka-actor Arrived Reporter Affected • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  110. 110. akka-actor Arrived Reporter Affected • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  111. 111. akka-actor Arrived Reporter Affected • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  112. 112. akka-cluster akka-persistence http://www.reactivemanifesto.org/ akka-actor • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  113. 113. akka-persistence Idle • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Attack
  114. 114. akka-persistence Idle Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  115. 115. akka-persistence Idle Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  116. 116. akka-persistence Sent Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  117. 117. akka-persistence Sent Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  118. 118. akka-persistence Sent Traveling Eventlog • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  119. 119. akka-persistence Traveling Sent Eventlog • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  120. 120. akka-persistence Traveling Sent Eventlog Reporter • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  121. 121. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Attack
  122. 122. akka-persistence Traveling Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  123. 123. akka-persistence Traveling Attack By default at-most-once delivery • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  124. 124. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Attack
  125. 125. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC Attack
  126. 126. akka-persistence Traveling Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  127. 127. akka-persistence Traveling Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  128. 128. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  129. 129. akka-persistence Traveling Ack at-least-once delivery • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  130. 130. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  131. 131. akka-persistence Traveling IFailedMasterException • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  132. 132. akka-persistence Traveling • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  133. 133. akka-persistence Idle Sent Eventlog Attack Sent • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  134. 134. akka-persistence Traveling Affected Eventlog Attack • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  135. 135. akka-persistence Traveling Sent Eventlog Recovery from EventLog • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  136. 136. akka-cluster akka-persistence http://www.reactivemanifesto.org/ akka-actor • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  137. 137. akka-cluster • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  138. 138. akka-cluster • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  139. 139. akka-cluster Red squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  140. 140. akka-cluster Blue squadron Red squadron Green squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  141. 141. akka-cluster Affected Affected Blue squadron Red squadron Affected Affected Green squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  142. 142. akka-cluster Affected Affected Blue squadron Red squadron Affected Affected Green squadron • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  143. 143. Final notes Aggregate hides implementation details Implementation is focused on a bounded context of the whole domain Think about messages, Focus your attention on interaction over data The less actors have interlocutors, the better. Take care about message senders. • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
  144. 144. Thanks @xbucchiotty xbucchiotty@xebia.fr • EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC

×