reactive domain driven design - elsassjug
DESCRIPTION
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 FranceTRANSCRIPT
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Reactive
Domain Driven Design
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
The Objective
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
The red squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Characters
/Alliance /Red squadron
/Empire / DeathStar
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Attackclass Alliance{ val squadrons = Set[Squadron]; ! def attack(empire){ ! val deathStar = empire.deathStar ! squadron.foreach(squadron => squadron.attack(deathStar) ) } }
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Idle
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class Squadron{ var location = base; ! def attack(){ travelTo(deathStar){ … this.location = deathStar … } ! } }
Traveling
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class Squadron{ val xwings = Set[Squadron]; ! def attack(deathStar){ travelTo(deathStar) ! do{ xwings.foreach(_.attack(deathStar)) }while(deathStar.alive) ! } }
Fighting
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class XWing{ var healthPoints = 1 ! def attack(deathStar){ ! deathStar.receiveTorpedoFrom(this) !!!! } }
Fighting
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class DeathStar{ var healthPoints = 100 ! def receiveTorpedoFrom(sender){ healthPoints -= 1 if(senderWithoutTheForce){ sender.receiveTorpedoFrom(this) } } !}
Fighting
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
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
Tasks
Notification from XWing to Squadron Notification from
Squadron to Alliance
Implements Squadron#retreat
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Notification from XWing to Squadron
class XWing{ var healthPoints = 1 !!! def receiveTorpedoFrom(sender){ ! println(s”$this is dead”) } }
• 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
• 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”) } }
Remember
No bidirectional
references
Notification from XWing to Squadron
• 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”) } } What would be
visibility of remove?
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”) } ! }
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 }
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 ) ) ! }
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
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 -= deadXWing ) ) ! }Loosely coupled
But we starts with
asynchronous
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 ) ) ! }
Notification from XWing to Squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Tasks
Notification from XWing to Squadron Notification from
Squadron to Alliance
Implements Squadron#retreat
• 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 = ??? }
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
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 ) ) !! }
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 = ??? }
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 = ??? }
Notification from Squadron to Alliance
Will make
the tests
green
• 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 = ??? }
Notification from Squadron to Alliance
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Tasks
Notification from Squadron to Alliance
Implements Squadron#retreat
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class Squadron{ var xwings = Set[XWing]() ! def retreat() = ??? !!!!!!}
Implements Squadron#retreat
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class Squadron{ var xwings = Set[XWing]() ! def retreat() = { travelTo(base) } !!!!!}
Implements Squadron#retreat
• 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
• 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
• 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
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
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
Tasks
Get current status as String from a Squadron
Notification at the end of travels
• 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
• 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
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Tasks
Get current status as String from a Squadron
Notification at the end of travels
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
class Squadron{ var xwings = Set[XWing]() !! !!!!!}
Get current status as String from a Squadron
• 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
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
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
Domain Driven Design
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.amazon.fr/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Technical core concepts
Aggregate
Bounded context
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Aggregate
Bounded contexttransaction
Technical core concepts
code
scalability
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
Knight
Knight
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Implementation is focused on a
bounded context of the whole domain
code scalability
Knight
Knight
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
Aggregate hides implementation
details
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
code scalability
Aggregate hides implementation
details
Implementation is focused on a
bounded context of the whole domain
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Aggregate
Bounded contexttransaction
Technical core concepts
code
scalability
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
?
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
Root entity ensures
consistency of the whole aggregate at any time
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
!
can see 4 XWings
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
!
can see 3 XWings
When the Alliance can see the changes?
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
transaction
!
can see 3 XWings
From an external point of view, the
aggregate is eventually
consistent!
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
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
Domain Driven Design
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Domain Driven Design ++
EventSourcing
CQRS
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
CQRSCommand 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
EventSourcing
Forget about Hibernate and other ORMs.
Persists meaningful past events.
!
Command ≠ Event
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Functional EventSourcing
Command State (Aggregate)x (Actions) Events
Decision making
Events x State (Aggregate)
apply State (Aggregate)
+
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Functional EventSourcing
Command State (Aggregate)x (Actions) Events
Decision making
Events x State (Aggregate)
apply State (Aggregate)
You don’t even need to persist
complete aggregates state !
+
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Functional EventSourcing
Command State (Aggregate)x Events
Decision making
Events x State (Aggregate)
apply State (Aggregate)
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Functional EventSourcing
Command State (Aggregate)x Events
Decision making
Events x State (Aggregate)
apply State (Aggregate)
source: @thinkbeforecoding !
https://github.com/thinkbeforecoding/FsUno.Prod
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Command ≠ EventCommand ≠ Query
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Command
ActionsEvent
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Command
ActionsEvent
But where are the views?
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Reporter
And the views?
You can keep specific views
inside aggregates. You’ll bother the root for
minor subjects. Lost(red-1)
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
And the views?
You read events log and build
ad-hoc views. !
In « real-time » or on demand.
Listener
Lost(red-1)
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
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
Reactive
Domain Driven Design
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Reactive
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
asynchronous
low coupling
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
scaling to workload
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
sane error and failure
handling
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
system always responds in bounded latency
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Tasks
Let’s do a refactor with Akka
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Aggregate
Red squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Characters
/Alliance /Red squadron
/Empire / DeathStar
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Actors
/Alliance /Red squadron
/Empire / DeathStar
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Functional EventSourcing
Command State (Aggregate)x Actions Events
Decision making +
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Messages
Attack ( DeathStarPath , Squadron )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Messages
Attack ( DeathStarPath , Squadron )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Idle
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
Sent ( Squadron, Destination )
Travel ( Squadron, Destination )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
Sent ( Squadron, Destination )
Travel ( Squadron, Destination )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
Arrived ( Squadron, Destination )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
Arrived ( Squadron, Destination )
Arrived ( Squadron, Destination )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Fighting
Fire ( DeathStarPath )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Fighting
Fire ( DeathStarPath )Fire ( XWingPath )Lost ( Squadron, XWing )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Fire ( DeathStarPath )
Messages
Sent ( Squadron, Destination )Arrived ( Squadron, Destination )
Arrived ( Squadron, Destination )
Travel ( Squadron, Destination )
Attack ( DeathStarPath , Squadron )
Lost ( Squadron, Destination )
Fire ( XWingPath )
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Algebras
Fire Fightingx Lost
Fighting Lostx Fighting
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Algebras
Fire Fightingx Lost
Fighting Lostx Fighting
Akka killing feature !
receive as Partial Function
context.become()
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Algebras
Fire Fightingx Lost
Fighting Lostx Fighting
Think about functions
validating inputs
for some outputs
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Algebras
Fire Fightingx Lost
Fighting Lostx Fighting
Finite State Machine !
For The Win
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Algebras
Fire Fightingx Lost
Fighting Lostx Fighting
NOW THE CODE
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
akka-actor
akka-cluster akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
Idle
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
IdleAttack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
Idle
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
Arrived
Reporter
Affected
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
Arrived Reporter
Affected
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-actor
Reporter
Affected
Arrived
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
akka-actor
akka-cluster akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-persistence
Idle
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
IdleAttack
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Idle
Attack
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
Sent
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Sent
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Eventlog
Sent
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
EventlogSent
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Reporter
EventlogSent
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
By default at-most-once delivery
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
Ack
at-least-once delivery
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
IFailedMasterException
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Idle
akka-persistence
EventlogSent
SentAttack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
EventlogAffected
Attack
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Traveling
akka-persistence
EventlogSent
Recovery from EventLog
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
http://www.reactivemanifesto.org/
akka-actor
akka-cluster akka-persistence
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
Red squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
Red squadronBlue squadron
Green squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
Red squadronBlue squadron
Green squadron
AffectedAffected
Affected Affected
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
akka-cluster
Red squadronBlue squadronAffectedAffected
Affected Affected
Green squadron
• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC
Final notesAggregate 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.