Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Fighting Bottlenecks with CQRS/ES ResearchGate Berlin Nov 30, 2013 Mathias Verraes @mathiasverraes verraes.net
Slide 2
Slide 2 text
Student of Systems Meddler of Models Labourer of Legacy
Slide 3
Slide 3 text
Blog verraes.net DDDBE domaindriven.be Podcast elephantintheroom.io
Slide 4
Slide 4 text
Business Problem A Simplified Model Command/Query Responsibility Segregation Event Sourcing Read Model Projections Eventual Consistency
Slide 5
Slide 5 text
Business Problem
Slide 6
Slide 6 text
Sell a gazillion concert tickets to desperate fans … in a hurry!
Slide 7
Slide 7 text
Don’t crash during peaks Don’t annoy our customers Don’t sell more than we have
Slide 8
Slide 8 text
A Simplified Model
Slide 9
Slide 9 text
Model invariants as a Presale Aggregate?
Slide 10
Slide 10 text
#reservedTickets #soldTickets #availableTickets Presale # Tickets
Slide 11
Slide 11 text
Model invariants as individual Ticket Aggregates
Slide 12
Slide 12 text
reserved sold available Individual Ticket status
Slide 13
Slide 13 text
Command/Query Responsibility Segregation
Slide 14
Slide 14 text
Client Remote Façade Application Services Domain Model ORM Database
Slide 15
Slide 15 text
Highly cohesive Read + Write Model?
Slide 16
Slide 16 text
Bottleneck
Slide 17
Slide 17 text
Client Database Database Remote Façade Application Services Domain Model ORM Eventually Consistent
Slide 18
Slide 18 text
CQRS challenges the assumption that reading and writing are supposed to share the same abstractions.
Slide 19
Slide 19 text
CQRS challenges the assumption that reading and writing are supposed to share the same models.
Slide 20
Slide 20 text
CQRS challenges the assumption that reading and writing are supposed to share the same databases.
Slide 21
Slide 21 text
CQRS challenges the assumption that reading and writing are supposed to share the same applications.
Slide 22
Slide 22 text
Segregation of read and write is a radical form of decoupling.
Slide 23
Slide 23 text
Client Domain Model Remote Façade Remote Façade Application Svcs Application Svcs Domain Model ORM ORM Database Database
Slide 24
Slide 24 text
Radical!
Slide 25
Slide 25 text
Client Write Model Read Model
Slide 26
Slide 26 text
Client Write Model Read Model DTO Commands Events
Slide 27
Slide 27 text
Interact with State Guard Invariants Project State
Slide 28
Slide 28 text
Task Based UI Event Store Polyglot Persistence
Slide 29
Slide 29 text
No content
Slide 30
Slide 30 text
Event Sourcing
Slide 31
Slide 31 text
TicketWasReserved [ ticketId, forUser, onDate ]
Slide 32
Slide 32 text
Ticket state = Ticket history ! TicketWasSold [ toUser ] TicketWasReserved [ forUser, onDate ] ReservationWasReleased [ ] TicketWasReserved [ forUser, onDate ] TicketWasPrinted [ inPresale ]
Slide 33
Slide 33 text
Mature domains already work this way ! AccountWasDebited [ 20 ] AccountWasDebited [ 10 ] AccountWasCredited [ 100 ] AccountWasOpened
Slide 34
Slide 34 text
BankAccount { debit(amount) { guardThatAccountIsNotOverdraft(amount) recordThat( new AccountWasDebited(amount) ) } }
Slide 35
Slide 35 text
BankAccount { apply(AccountWasDebited event) { amount = amount - event.amount } }
Slide 36
Slide 36 text
BankAccount { getRecordedEvents() {} reconstituteFromHistory(eventHistory) {} }
Slide 37
Slide 37 text
Read Model Projections
Slide 38
Slide 38 text
TicketWasSold TicketWasReserved ReservationWasReleased TicketWasReserved TicketWasPrinted Ticket ! !
Slide 39
Slide 39 text
TicketWasSold TicketWasReserved ReservationWasReleased TicketWasReserved TicketWasPrinted AvailableTicket TotalNumberOfAvailableTickets AverageNumberOfTicketsPerBuyer AverageNumberOfReleasesPerTicket
Slide 40
Slide 40 text
Eventual Consistency
Slide 41
Slide 41 text
Writes are immediately consistent Reads are eventually consistent
Slide 42
Slide 42 text
Many issues stemming from eventual consistency can be solved in the user interface
Slide 43
Slide 43 text
A Ticket can only be sold once. How do we know it’s available?
Slide 44
Slide 44 text
Get a batch of x*2 PossiblyAvailableTickets ! ReserveTicket ack/nack loop while acks < 3 To buy x tickets:
Slide 45
Slide 45 text
More? ! Testing Context Mapping Event Storming Process Managers Occasionally Connected Systems Reporting Legacy Integrations …
Slide 46
Slide 46 text
Questions? verraes.net @mathiasverraes