SlideShare une entreprise Scribd logo
1  sur  33
Télécharger pour lire hors ligne
Event-sourcing
avancé
avec Scala
PSUG - Jonathan Winandy &
Valentin Kasas
1
Agenda
● Eventsourcing : qu’es aquò ?
● Patterns et anti-patterns
● Streaming et métadonnées
● Typage et sérialisation
2
Qui sommes-nous ?
Jonathan Winandy
@ahoy_jon
● Data engineer / Hardware destroyer
● Eventsourcer since before it was cool
● Scala/Java/Clojure
● CYM
● hipster
Valentin Kasas
@ValentinKasas
● Web engineer / homme-orchestre
● Eventsourcer since 2013
● Scala :: scala :: HNil
● Freelance
● dandy
3
Eventsourcing : définitions
4
EventSourcing : définition
● Une idée maîtresse : prendre comme source de vérité la succession des
événements qui surviennent dans un système
● Plutôt que s’appuyer sur un représentation muable du présent, on
s’appuie sur l’enregistrement des événements passés et immuables.
5
RDBMS vs EventSourcing
Source http://docs.geteventstore.com/introduction/img/transactional-model-with-delete.png
VS
Source https://martin.kleppmann.com/2015/03/insideout-06.png
6
RDBMS vs EventSourcing
7
EventSourcing, au niveau des API 1/2
trait Stream[M[_]] {
val name: String
def append(event: Event, events: Event*): M[WriteCompleted]
def read(position: Int): M[Event]
}
case class Event(evenType: String, id: UUID, body: Content, metadata: Content)
case class WriteCompleted(start: Int, end: Int)
8
EventSourcing, au niveau des API 2/2
trait Stream[M[_]] {
def readPage(fromPosition: Int, pageSize: Int,
readDirection: ReadDirection = Forward): M[Page]
def subscribeTo(observer: SubscriptionObserver): Closeable
def subscribeToFrom(observer: SubscriptionObserver, position: Int): Closeable
}
case class Page(events: List[Event], fromPosition: Int,
nextPosition: Int, readDirection: ReadDirection)
trait SubscriptionObserver {
def onLiveProcessingStart(subscription: Closeable)
def onEvent(event: Event, subscription: Closeable)
def onError(e: Throwable)
def onClose()
}
9
Modèle basique
95 96 97 98
append
append
append
read(95)
read(96)
read(97)
10
Invariant(s)
∀p ∈ ℕ, et pour une définition de
‘=‘
x := read(p)
y := read(p)
‘x ≠ ⊥’ ⇒ x = y
Plus simplement :
La cacheabilité est infinie.
Une fois qu’un élément est
disponible à une position (p), cet
élément sera identique (=) pour
toujours.
11
EventSourcing : les avantages
Conserver l’intégralité de l’historique d’un système offre de nombreux
avantages :
● Plus proche de la réalité (perception),
● Auditabilité,
● Observabilité de la nouveauté,
● Simplicité de consommation,
● Réinterprêtation de l’historique (BI for “Free”).
● Facilite (beaucoup) CQRS
Decision
Apply
commande
état
event
Read
Model
Read
Model
Read
Model 12
EventSourcing : les inconvénients
L’eventsourcing présente aussi quelques inconvénients :
● Consommation d’espace disque plus importante (et en constante
augmentation),
● Démarrage potentiellement plus long (il faut relire tout l’historique),
● Difficile de changer le schéma des événements (<= immuabilité).
● Découpage en streams, et opérations sur plusieurs streams.
● Multiplication des états (read models, Monoid[Event]).
● Gestion asynchrone.
13
Patterns et anti-patterns
14
Patterns
● Algébre d’événement (List[Event] à la place de A * List[Event]),
● Génération d’id non coordonnée => UUID,
● Quantification de la donnée,
● Capture des réglès métier complexes, et décisions peu reproductibles.
● Corrélation et causation
● Sagas
15
Anti-Patterns
● CRUD Sourcing
● Command Sourcing
● Make-My-Sum-Type Grow
16
Streaming, métadonnées et metastreams
17
Pourquoi ajouter des métadonnées ?
● Les events contiennent la donnée métier, mais on a aussi besoin de
données techniques pour :
○ Expliciter le contexte d’écriture (instance, saga, commande, position dans la commande).
○ Périniser la donnée (schéma à l’écriture).
○ Tracer la provenance (de qui, de la part de).
○ Séparer la donnée entre différent environnement partageant la même infrastructure.
18
Quels types de métadonnées ?
● Métadonnées des événements
○ Corrélation & causation
○ Informations de type (schéma, on y reviendra)
○ etc...
● Méta-streams (ou streams de méta-events) d’informations techniques sur
le système
○ Instances
○ Schémas
19
Types et sérialisation
20
Pourquoi/comment typer les streams ?
● Sans typage, pas d’albèbre, pas moyen d’écrire
○ state = events.foldLeft(initial)(_ apply _)
● Problème : comment conserver le type des “vieux” events ?
● Quand le schéma des events change, on doit pouvoir
○ Upcaster les anciens events dans le nouveaux schéma (pour pouvoir démarrer une
nouvelle instance sur les anciennes données)
○ Downcaster les nouveaux events (pour que les anciennes instances continuent de
fonctionner pendant la mise à jour)
21
API typée : définition
case class Event[E](event:E, id:UUID, metadata:Metadata)
trait TypedStream[M[_], E] {
implicit val coproductEvidence: Generic[E]
implicit val serializableEvidence:AkiraSerializable[E]
val name: String @@ StreamId
def append(event: Event[E], events: Event[E]*): M[WriteCompleted]
def read(position: Int): M[Event[E]]
}
22
API typée : usage
sealed trait MQTTEvent
case class Disconnected(clientID: String) extends MQTTEvent
case class Published(clientID: String,
payload: Seq[Byte],
topicName: String) extends MQTTEvent
val mqttStream:TypedStream[Id,MQTTEvent] = ___
mqttStream.append(___)
23
Comment sérialiser les événements ?
L’EventSourcing nécessite une bonne sérialisation, car les événements vont
être écrits et consommés par :
● Beaucoup de programmes (dans des langages différents).
● Beaucoup d’intermédiaires.
● Pendant plusieurs années.
Une bonne sérialisation est :
● Extensible.
● Auto descriptible.
● Peut être lue et écrite de manière générique et indépendante.
24
Comment sérialiser les messages ?
Pour l’instant, nous utilisons Avro 1.8.x avec l’encodeur JSON,
mais c’est un détail d’implémentation.
25
● Conserver les schémas (passés et actuels) de tous les types d’événements
○ Dans les métadonnées de chaque événement, placer une référence vers le schéma dudit
événement
○ Dans un métastream dédié, stocker une représentation générique de chaque schéma
(sous la forme d’événements SchemaCreated
● Il faut aussi conserver le schéma des métadonnées
● Au démarrage, on utilise le méta stream des schémas pour initialiser le
Schéma Registry
● Problème de l’oeuf et de la poule
○ quel schéma pour les événements du stream schémas ?
○ sur quel stream les enregistre-t-on ?
Schema registry
26
Séquence de démarrage
schemas
meta
stream-xyz
SchemaCreated
<Metadata>
hash : “ab12ce9”
Schema : { “typ..
SchemaCreated
<InstanceUp>
hash : “56f3e05”
Schema : { “typ..
InstanceUp
data : nodeXYZ
meta : 56f3e05
SchemaCreated
<SmthHappened>
hash : “76b4ed0”
Schema : { “typ..
SmthHappened
data : {‘d’:”123”}
meta : 76b4ed0
SmthHappened
data : {‘d’:”abc”}
meta : 76b4ed0
SchemaCreated
<SchemaCreated>
hash : “2d163b9”
Schema : { “typ..
Application démarrée
27
Séquence de démarrage
● Au démarrage, on initialise le Schema Registry
● Comme le méta stream schémas est vide on enregistre les schémas “par
defaut” :
○ Le schéma de SchemaCreated
○ Le schéma des métadonnées
● On veut ensuite enregistrer le démarrage d’une nouvelle instance
(InstanceUp)
○ Le schéma d’InstanceUp n’existe pas, il faut l’enregistrer
○ On émet un InstanceUp dans le méta schéma
● L’application est démarrée
● Avant d’enregistrer un nouvel event, on vérifie que son schéma est
présent dans le registry, et on l’enregistre si besoin
28
Evolution des types
A + BA A + B + C
auto auto
BA
f: A → B
Record with aliased fieldsRecord
auto
wideningnarrowing
A × BA × B × C A
auto auto
projectionadd field
29
Evolution des types
A × BA × B × C A
auto auto
projectionadd field
A × B × Czero
auto
A × B × (C + Czero
)
auto
auto
auto
add field with
default value
auto
Czero
<: C
A @@ B auto
A
auto
A as logical type A @@ B
Type level
Serialization level
A @@ B <: A
30
Evolution des types dans le temps
A1
A2
A3
autoauto auto
× A4
?
f
B1
stream-xyz : A1
+ B1
A2
+ B1
A3
+ B1
autoauto A4
? + B1
A’4
+ A3
+ B1
Gérer la compatibilité
entre A3
et A4
.
Poser A4
à coté de A3
.
Deux solutions :
auto
31
Conclusion
● L’EventSourcing c’est bon, mangez-en !
● Les principaux problèmes pénibles ont des solutions
● Coming soon : Akira (https://github.com/vil1/akira)
32
MerciPour les questions, demandez Sam
33

Contenu connexe

Similaire à Event-sourcing avancé avec Scala

Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...Bruno Bonnin
 
Spark Streaming
Spark StreamingSpark Streaming
Spark StreamingPALO IT
 
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...#OSSPARIS19 - Stream processing : de la base de données classique au streamin...
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...Paris Open Source Summit
 
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...Publicis Sapient Engineering
 
Construire un data lake managé - GDG Paris - Juin 2019
Construire un data lake managé - GDG Paris - Juin 2019Construire un data lake managé - GDG Paris - Juin 2019
Construire un data lake managé - GDG Paris - Juin 2019Jean-Baptiste Claramonte
 
Volcamp 2023 - Compter les moutons à grande échelle
Volcamp 2023 - Compter les moutons à grande échelleVolcamp 2023 - Compter les moutons à grande échelle
Volcamp 2023 - Compter les moutons à grande échelleKarim Bogtob
 
Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Aymeric Roffé
 
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics Marius Zaharia
 
Workshop Spring - Session 4 - Spring Batch
Workshop Spring -  Session 4 - Spring BatchWorkshop Spring -  Session 4 - Spring Batch
Workshop Spring - Session 4 - Spring BatchAntoine Rey
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQLBruno Bonnin
 
Implémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexesImplémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexesGeeks Anonymes
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaOlivier BAZOUD
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQLBruno Bonnin
 
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...Sébastien Prunier
 
Monitoring d'applications/environnements PHP : APM et Pinba
Monitoring d'applications/environnements PHP : APM et PinbaMonitoring d'applications/environnements PHP : APM et Pinba
Monitoring d'applications/environnements PHP : APM et PinbaIdaf_1er
 
BBL - Monitoring - kyriba
BBL - Monitoring - kyribaBBL - Monitoring - kyriba
BBL - Monitoring - kyribaOlivier BAZOUD
 

Similaire à Event-sourcing avancé avec Scala (20)

Tsung GIS
Tsung GISTsung GIS
Tsung GIS
 
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
 
Mongo DB
Mongo DBMongo DB
Mongo DB
 
Spark Streaming
Spark StreamingSpark Streaming
Spark Streaming
 
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...#OSSPARIS19 - Stream processing : de la base de données classique au streamin...
#OSSPARIS19 - Stream processing : de la base de données classique au streamin...
 
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...
XebiCon'17 : Monitoring et métrologie pour les conteneurs - Jean-Pascal Thie...
 
Vert.x 3
Vert.x 3Vert.x 3
Vert.x 3
 
Construire un data lake managé - GDG Paris - Juin 2019
Construire un data lake managé - GDG Paris - Juin 2019Construire un data lake managé - GDG Paris - Juin 2019
Construire un data lake managé - GDG Paris - Juin 2019
 
Volcamp 2023 - Compter les moutons à grande échelle
Volcamp 2023 - Compter les moutons à grande échelleVolcamp 2023 - Compter les moutons à grande échelle
Volcamp 2023 - Compter les moutons à grande échelle
 
Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13Voodoo.io NodeJS Meetup - November 13
Voodoo.io NodeJS Meetup - November 13
 
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics
Sql Saturday Paris 2016 - De StreamInsight à Azure Stream Analytics
 
Workshop Spring - Session 4 - Spring Batch
Workshop Spring -  Session 4 - Spring BatchWorkshop Spring -  Session 4 - Spring Batch
Workshop Spring - Session 4 - Spring Batch
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQL
 
Implémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexesImplémentation efficace et durable de processus métiers complexes
Implémentation efficace et durable de processus métiers complexes
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - Xebia
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQL
 
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...
Poitou Charentes JUG - Traçabilité dans une architecture distribuée avec Node...
 
Dijkstra kshortest
Dijkstra kshortestDijkstra kshortest
Dijkstra kshortest
 
Monitoring d'applications/environnements PHP : APM et Pinba
Monitoring d'applications/environnements PHP : APM et PinbaMonitoring d'applications/environnements PHP : APM et Pinba
Monitoring d'applications/environnements PHP : APM et Pinba
 
BBL - Monitoring - kyriba
BBL - Monitoring - kyribaBBL - Monitoring - kyriba
BBL - Monitoring - kyriba
 

Event-sourcing avancé avec Scala

  • 1. Event-sourcing avancé avec Scala PSUG - Jonathan Winandy & Valentin Kasas 1
  • 2. Agenda ● Eventsourcing : qu’es aquò ? ● Patterns et anti-patterns ● Streaming et métadonnées ● Typage et sérialisation 2
  • 3. Qui sommes-nous ? Jonathan Winandy @ahoy_jon ● Data engineer / Hardware destroyer ● Eventsourcer since before it was cool ● Scala/Java/Clojure ● CYM ● hipster Valentin Kasas @ValentinKasas ● Web engineer / homme-orchestre ● Eventsourcer since 2013 ● Scala :: scala :: HNil ● Freelance ● dandy 3
  • 5. EventSourcing : définition ● Une idée maîtresse : prendre comme source de vérité la succession des événements qui surviennent dans un système ● Plutôt que s’appuyer sur un représentation muable du présent, on s’appuie sur l’enregistrement des événements passés et immuables. 5
  • 6. RDBMS vs EventSourcing Source http://docs.geteventstore.com/introduction/img/transactional-model-with-delete.png VS Source https://martin.kleppmann.com/2015/03/insideout-06.png 6
  • 8. EventSourcing, au niveau des API 1/2 trait Stream[M[_]] { val name: String def append(event: Event, events: Event*): M[WriteCompleted] def read(position: Int): M[Event] } case class Event(evenType: String, id: UUID, body: Content, metadata: Content) case class WriteCompleted(start: Int, end: Int) 8
  • 9. EventSourcing, au niveau des API 2/2 trait Stream[M[_]] { def readPage(fromPosition: Int, pageSize: Int, readDirection: ReadDirection = Forward): M[Page] def subscribeTo(observer: SubscriptionObserver): Closeable def subscribeToFrom(observer: SubscriptionObserver, position: Int): Closeable } case class Page(events: List[Event], fromPosition: Int, nextPosition: Int, readDirection: ReadDirection) trait SubscriptionObserver { def onLiveProcessingStart(subscription: Closeable) def onEvent(event: Event, subscription: Closeable) def onError(e: Throwable) def onClose() } 9
  • 10. Modèle basique 95 96 97 98 append append append read(95) read(96) read(97) 10
  • 11. Invariant(s) ∀p ∈ ℕ, et pour une définition de ‘=‘ x := read(p) y := read(p) ‘x ≠ ⊥’ ⇒ x = y Plus simplement : La cacheabilité est infinie. Une fois qu’un élément est disponible à une position (p), cet élément sera identique (=) pour toujours. 11
  • 12. EventSourcing : les avantages Conserver l’intégralité de l’historique d’un système offre de nombreux avantages : ● Plus proche de la réalité (perception), ● Auditabilité, ● Observabilité de la nouveauté, ● Simplicité de consommation, ● Réinterprêtation de l’historique (BI for “Free”). ● Facilite (beaucoup) CQRS Decision Apply commande état event Read Model Read Model Read Model 12
  • 13. EventSourcing : les inconvénients L’eventsourcing présente aussi quelques inconvénients : ● Consommation d’espace disque plus importante (et en constante augmentation), ● Démarrage potentiellement plus long (il faut relire tout l’historique), ● Difficile de changer le schéma des événements (<= immuabilité). ● Découpage en streams, et opérations sur plusieurs streams. ● Multiplication des états (read models, Monoid[Event]). ● Gestion asynchrone. 13
  • 15. Patterns ● Algébre d’événement (List[Event] à la place de A * List[Event]), ● Génération d’id non coordonnée => UUID, ● Quantification de la donnée, ● Capture des réglès métier complexes, et décisions peu reproductibles. ● Corrélation et causation ● Sagas 15
  • 16. Anti-Patterns ● CRUD Sourcing ● Command Sourcing ● Make-My-Sum-Type Grow 16
  • 17. Streaming, métadonnées et metastreams 17
  • 18. Pourquoi ajouter des métadonnées ? ● Les events contiennent la donnée métier, mais on a aussi besoin de données techniques pour : ○ Expliciter le contexte d’écriture (instance, saga, commande, position dans la commande). ○ Périniser la donnée (schéma à l’écriture). ○ Tracer la provenance (de qui, de la part de). ○ Séparer la donnée entre différent environnement partageant la même infrastructure. 18
  • 19. Quels types de métadonnées ? ● Métadonnées des événements ○ Corrélation & causation ○ Informations de type (schéma, on y reviendra) ○ etc... ● Méta-streams (ou streams de méta-events) d’informations techniques sur le système ○ Instances ○ Schémas 19
  • 21. Pourquoi/comment typer les streams ? ● Sans typage, pas d’albèbre, pas moyen d’écrire ○ state = events.foldLeft(initial)(_ apply _) ● Problème : comment conserver le type des “vieux” events ? ● Quand le schéma des events change, on doit pouvoir ○ Upcaster les anciens events dans le nouveaux schéma (pour pouvoir démarrer une nouvelle instance sur les anciennes données) ○ Downcaster les nouveaux events (pour que les anciennes instances continuent de fonctionner pendant la mise à jour) 21
  • 22. API typée : définition case class Event[E](event:E, id:UUID, metadata:Metadata) trait TypedStream[M[_], E] { implicit val coproductEvidence: Generic[E] implicit val serializableEvidence:AkiraSerializable[E] val name: String @@ StreamId def append(event: Event[E], events: Event[E]*): M[WriteCompleted] def read(position: Int): M[Event[E]] } 22
  • 23. API typée : usage sealed trait MQTTEvent case class Disconnected(clientID: String) extends MQTTEvent case class Published(clientID: String, payload: Seq[Byte], topicName: String) extends MQTTEvent val mqttStream:TypedStream[Id,MQTTEvent] = ___ mqttStream.append(___) 23
  • 24. Comment sérialiser les événements ? L’EventSourcing nécessite une bonne sérialisation, car les événements vont être écrits et consommés par : ● Beaucoup de programmes (dans des langages différents). ● Beaucoup d’intermédiaires. ● Pendant plusieurs années. Une bonne sérialisation est : ● Extensible. ● Auto descriptible. ● Peut être lue et écrite de manière générique et indépendante. 24
  • 25. Comment sérialiser les messages ? Pour l’instant, nous utilisons Avro 1.8.x avec l’encodeur JSON, mais c’est un détail d’implémentation. 25
  • 26. ● Conserver les schémas (passés et actuels) de tous les types d’événements ○ Dans les métadonnées de chaque événement, placer une référence vers le schéma dudit événement ○ Dans un métastream dédié, stocker une représentation générique de chaque schéma (sous la forme d’événements SchemaCreated ● Il faut aussi conserver le schéma des métadonnées ● Au démarrage, on utilise le méta stream des schémas pour initialiser le Schéma Registry ● Problème de l’oeuf et de la poule ○ quel schéma pour les événements du stream schémas ? ○ sur quel stream les enregistre-t-on ? Schema registry 26
  • 27. Séquence de démarrage schemas meta stream-xyz SchemaCreated <Metadata> hash : “ab12ce9” Schema : { “typ.. SchemaCreated <InstanceUp> hash : “56f3e05” Schema : { “typ.. InstanceUp data : nodeXYZ meta : 56f3e05 SchemaCreated <SmthHappened> hash : “76b4ed0” Schema : { “typ.. SmthHappened data : {‘d’:”123”} meta : 76b4ed0 SmthHappened data : {‘d’:”abc”} meta : 76b4ed0 SchemaCreated <SchemaCreated> hash : “2d163b9” Schema : { “typ.. Application démarrée 27
  • 28. Séquence de démarrage ● Au démarrage, on initialise le Schema Registry ● Comme le méta stream schémas est vide on enregistre les schémas “par defaut” : ○ Le schéma de SchemaCreated ○ Le schéma des métadonnées ● On veut ensuite enregistrer le démarrage d’une nouvelle instance (InstanceUp) ○ Le schéma d’InstanceUp n’existe pas, il faut l’enregistrer ○ On émet un InstanceUp dans le méta schéma ● L’application est démarrée ● Avant d’enregistrer un nouvel event, on vérifie que son schéma est présent dans le registry, et on l’enregistre si besoin 28
  • 29. Evolution des types A + BA A + B + C auto auto BA f: A → B Record with aliased fieldsRecord auto wideningnarrowing A × BA × B × C A auto auto projectionadd field 29
  • 30. Evolution des types A × BA × B × C A auto auto projectionadd field A × B × Czero auto A × B × (C + Czero ) auto auto auto add field with default value auto Czero <: C A @@ B auto A auto A as logical type A @@ B Type level Serialization level A @@ B <: A 30
  • 31. Evolution des types dans le temps A1 A2 A3 autoauto auto × A4 ? f B1 stream-xyz : A1 + B1 A2 + B1 A3 + B1 autoauto A4 ? + B1 A’4 + A3 + B1 Gérer la compatibilité entre A3 et A4 . Poser A4 à coté de A3 . Deux solutions : auto 31
  • 32. Conclusion ● L’EventSourcing c’est bon, mangez-en ! ● Les principaux problèmes pénibles ont des solutions ● Coming soon : Akira (https://github.com/vil1/akira) 32
  • 33. MerciPour les questions, demandez Sam 33