Slide 1

Slide 1 text

Building an event sourced system in .NET Michiel Overeem Lead Software Architect michiel.overeem@afas.nl @michielovereem

Slide 2

Slide 2 text

400+ employees (4 locations) 10.500 customers (companies) AFAS Software

Slide 3

Slide 3 text

HRM, CRM, finance, order management, project management, workflow, ... AFAS Profit

Slide 4

Slide 4 text

20 years of ERP 10.000 customers 90% cloud Web Scalable CQRS Event sourcing

Slide 5

Slide 5 text

20 years of ERP 10.000 customers 90% cloud Person Entity Customer Role Order Agreement party Spending limit Address Organisation Entity Delivery BusinessAc tivity party Invoice BusinessAc tivity party Address Address Spending limit Spending limit Own Organisation Workarea workarea Spending limit Put all our knowledge and experience in a model

Slide 6

Slide 6 text

Customized Web Scalable CQRS Event sourcing Person Entity Customer Role Order Agreement party Spending limit Address Organisation Entity Delivery BusinessAc tivity party Invoice BusinessAc tivity party Address Address Spending limit Spending limit Own Organisation Workarea workarea Spending limit

Slide 7

Slide 7 text

(2.830 tables with 126.705 columns) ERP software is inherently relational

Slide 8

Slide 8 text

Command Query Responsibility Segregation Client Command system Query system Eventing system

Slide 9

Slide 9 text

Command Query Responsibility Segregation Client Command system Query system Eventing system “PlaceOrderCommand”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] }

Slide 10

Slide 10 text

Command Query Responsibility Segregation Client Command system Query system Eventing system “GetOrders”: { “CustomerName”: “Linus Torvalds”, }

Slide 11

Slide 11 text

Command Query Responsibility Segregation Client Command system Query system Eventing system

Slide 12

Slide 12 text

DDD

Slide 13

Slide 13 text

Aggregates - independent, self-contained business objects that handle commands and raise events.

Slide 14

Slide 14 text

Aggregates

Slide 15

Slide 15 text

Aggregates “PlaceOrderCommand”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] }

Slide 16

Slide 16 text

Aggregates “PlaceOrderCommand”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] } “OrderPlacedEvent”: { “OrderId”: “0b81b458-7671-4e9b-844b-9934255f5406”, “CustomerName”: “Linus Torvalds”, “OrderLines”: [ … ] }

Slide 17

Slide 17 text

Aggregates

Slide 18

Slide 18 text

Aggregates

Slide 19

Slide 19 text

Aggregates - independent, self-contained business objects that handle commands and raise events. That sounds a lot like actors ☺

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Events – Something that has happened.

Slide 22

Slide 22 text

Events Events that need to be processed in the query system.

Slide 23

Slide 23 text

Projectors – A process that builds a projection from events.

Slide 24

Slide 24 text

Projectors

Slide 25

Slide 25 text

Projectors Needs routing to find the correct store

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

How to get the events from the command system to the query system?

Slide 28

Slide 28 text

CQRS Client Command system Query system Eventing system Some kind of message bus?

Slide 29

Slide 29 text

Event push

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

T

Slide 32

Slide 32 text

2 phase commit Independence Command system Query system Eventing system

Slide 33

Slide 33 text

Event push

Slide 34

Slide 34 text

Event pull But we need persistence. And we still have a 2 phase commit.

Slide 35

Slide 35 text

Use the emitted events as single source of truth Event sourcing

Slide 36

Slide 36 text

CQRS Client Command system Query system Eventing system What is the data model used in the command side?

Slide 37

Slide 37 text

CQRS Client Command system Query system Eventing system

Slide 38

Slide 38 text

Event Store StreamId Stream Revision PayloadItemName Payload StreamType Sequence Number CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …

Slide 39

Slide 39 text

Aggregates loading Event Store StreamId Stream Revision PayloadItemName Payload StreamType Sequence Number CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …

Slide 40

Slide 40 text

Event processing Event Store StreamId Stream Revision PayloadItemName Payload StreamType Sequence Number CommitTime AccountId Person1 1 PersonCreatedEvent { … } Person 1 … … Person1 2 PersonUpdatedEvent { … } Person 2 … … Person2 1 PersonCreatedEvent { … } Person 3 … … Order1 1 OrderCreatedEvent { … } Order 1 … … Order2 1 OrderCreatedEvent { … } Order 2 … … Order3 1 OrderCreatedEvent { … } Order 3 … …

Slide 41

Slide 41 text

Event Sourcing A B A E C D D F B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2

Slide 42

Slide 42 text

Event Sourcing A B A E C D D F B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2 Sequencenumbers for projectors

Slide 43

Slide 43 text

Event Sourcing A B A E C D D F B B A C C G H D A B C A D A A A A A A B B C C 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 1 1 2 1 1 2 3 4 5 1 1 2 1 2 Revisions for aggregate loading and concurrency control

Slide 44

Slide 44 text

Event sourcing This is both the store as the messaging system.

Slide 45

Slide 45 text

Eventual consistency

Slide 46

Slide 46 text

Eventual consistency

Slide 47

Slide 47 text

Eventual consistency This is an async process

Slide 48

Slide 48 text

Eventual consistency Client Command system Query system Eventing system

Slide 49

Slide 49 text

Notifications β α γ

Slide 50

Slide 50 text

Notifications β α γ

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

Projector optimization

Slide 53

Slide 53 text

Projection Information from the customer stream Information from the order stream

Slide 54

Slide 54 text

Projection A helper-table with customer info A table for the projection A customer update could mean that we need to update 1.000.000+ rows

Slide 55

Slide 55 text

Projection: joins A table with customer info A table for the projection A query should join the two tables.

Slide 56

Slide 56 text

Projection: duplication A table with customer info A table with order info A table with customer info A table with invoice info

Slide 57

Slide 57 text

Projection: combine A table with customer info A table with order info A table with invoice info

Slide 58

Slide 58 text

Projection: chaining

Slide 59

Slide 59 text

So what have we seen?

Slide 60

Slide 60 text

Summary

Slide 61

Slide 61 text

Summary β α γ

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Building an event sourced system in .NET michiel.overeem@afas.nl @michielovereem