Slide 1

Slide 1 text

Fun.CQRS Functional and Fun CQRS in Scala

Slide 2

Slide 2 text

Agenda DDD / CQRS / Event Sourcing Aggregates / Commands / Events in Scala Akka and asynchrounous programming Akka Persistence and Event Sourcing

Slide 3

Slide 3 text

Not About Akka Typed "Function and Reactive Domain Modeling" - Debasish Ghosh

Slide 4

Slide 4 text

DDD / CQRS / ES Aggregate is a DDD concept. It has a root and zero or more entities and value objects underneath Commands and Events are used in CQRS Events can be persisted and replayed

Slide 5

Slide 5 text

Event Driven / Sourcing CQRS is Event Driven, but not necessarily implements Event Sourcing in synchronous CQRS: tx(Cmd ⇒ Aggregate ⇒ Event ⇒ View) in asynchronous CQRS: tx(Cmd ⇒ Aggregate ⇒ Event) tx(Event ⇒ View)

Slide 6

Slide 6 text

Scala And CQRS On creation C m d = > E v e n t E v e n t = > A g g r e g a t e / / t h e r e f o r e w e h a v e C m d = > ( A g g r e g a t e , E v e n t ) Post-creation ( A g g r e g a t e , C m d ) = > S e q [ E v e n t ] ( A g g r e g a t e , E v e n t ) = > A g g r e g a t e / / t h e r e f o r e w e h a v e ( A g g r e g a t e , C m d ) = > ( A g g r e g a t e , S e q [ E v e n t ] )

Slide 7

Slide 7 text

Async API On creation C m d = > F u t u r e [ E v e n t ] E v e n t = > A g g r e g a t e / / t h e r e f o r e w e h a v e C m d = > F u t u r e [ ( A g g r e g a t e , E v e n t ) ] Post-creation ( A g g r e g a t e , C m d ) = > F u t u r e [ S e q [ E v e n t ] ] ( A g g r e g a t e , E v e n t ) = > A g g r e g a t e / / t h e r e f o r e w e h a v e ( A g g r e g a t e , C m d ) = > F u t u r e [ ( A g g r e g a t e , S e q [ E v e n t ] ) ]

Slide 8

Slide 8 text

Async API - Inconvenience On creation ( c m d : C r e a t e F o o ) = > F u t u r e . s u c c e s s f u l ( F o o C r e a t e d ( " f o o " ) ) Post-creation ( f o o : F o o , c m d : C h a n g e N a m e ) = > F u t u r e . s u c c e s s f u l ( S e q ( F o o N a m e C h a n g e d ( " b a r " ) ) )

Slide 9

Slide 9 text

Sync/Async API - Lift On creation C m d = > E v e n t C m d = > F u t u r e [ E v e n t ] / / Y e a h ! ! C m d = > T h r o w a b l e Post-creation ( A g g r e g a t e , C m d ) = > E v e n t ( A g g r e g a t e , C m d ) = > S e q [ E v e n t ] ( A g g r e g a t e , C m d ) = > F u t u r e [ E v e n t ] ( A g g r e g a t e , C m d ) = > F u t u r e [ S e q [ E v e n t ] ] / / Y e a h ! ! ( A g g r e g a t e , C m d ) = > T h r o w a b l e

Slide 10

Slide 10 text

Akka And DDD/CQRS Is the Aggregate an Actor? Or does it live inside an Actor? If it lives inside an Actor, the Actor must know it’s hosting an Aggregate Akka Persistence for Event Sourcing Akka Persistence Query for generating Views (experimental)

Slide 11

Slide 11 text

Protocol And Behavior Protocol is the set of commands and events for a given Aggregate Behavior is the implementation Conditions to accept commands Possible failures Modify Aggregate state

Slide 12

Slide 12 text

Protocol And Behavior ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ A g g r e g a t e │ │ P r o t o c o l │ │ │ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ t y p e P r o t o c o l │ │ C o m m a n d s │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ │ │ E v e n t s │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ B e h a v i o r [ A g g r e g a t e ] │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

Slide 13

Slide 13 text

AggregateManager Create AggregateActors by id Forward messages to right AggregateActors ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ A g g r e g a t e M a n a g e r │ ─ ─ ─ ─ ─ ┐ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ A g g r e g a t e A c t o r ├ ─ ┐ └ ┬ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ├ ─ ┐ └ ─ ┬ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

Slide 14

Slide 14 text

AggregateActor AggregateActor is initialized with Behavior of Foo Responsible for Foo lifecycle and events storing ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ A g g r e g a t e A c t o r │ ─ ─ ─ ─ ─ ─ ─ ┐ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ B e h a v i o r [ F o o ] │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ Protocol messages are sent to Actor and applied to Aggregate through its Behavior

Slide 15

Slide 15 text

Projections We read from the Event Store to produce Views Akka Persistence Query new experimental module Produces a Reactive Stream source with the selected events

Slide 16

Slide 16 text

Shop Aggregates Customer just info from a customer Product create, change name and change price Order (references Customer and Products by identifier) created for a customer add / remove products execute / cancel

Slide 17

Slide 17 text

Shop Projections Customer Aggregate event → CustomerView Product Aggregate event → ProductView Customer, Product and Order events → OrderView

Slide 18

Slide 18 text

Problem With OrderViewProjection What to do with Events from Customer and Product? They will probably arrive before the first order is created. Should we query the CustomerViewRepo and ProductViewReop whenever we need more info? Will they reflect the expected state?

Slide 19

Slide 19 text

Solutions 1. Have one single event stream and one consumer can be a serious bottleneck 2. Implement specific logic for each single event for each view can lead to increasing complexity 3. Copy data by reusing existing projections, but saving in another Repository need for more storage, but simpler and reusable code Demo project uses that approach (check it) 4. Synchronous views, at least the main views Response time penalty, but better user feedback

Slide 20

Slide 20 text

Thank You! http://twitter.com/@renatocaval https://github.com/strongtyped/fun-cqrs