Reactive Domain Driven Design - elsassjug

Preview:

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 France

Citation preview

• 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.

• EBIA ALLIANCE = XEBIA + XEBIALABS + THIGA + UX REPUBLIC

Thanks

@xbucchiotty xbucchiotty@xebia.fr

Recommended