If there is a common practice in architecting software systems, it is to have them store the last known state of business entities in a relational database: though widely adopted and effectively supported by existing development tools, this practice trades the easiness of implementation with the cost of losing the history of such entities.
Event Sourcing provides a pivotal solution to this problem, giving systems the capability of restoring the state they had at any given point in time. Furthermore, injecting mock-up events and having them replayed by the business logic allows for an easy implementation of simulations and “what if” scenarios.
In this session, Andrea will demonstrate how to design time travelling systems by examining real-world, production-tested solutions.
The Fine Art of Time Travelling - Implementing Event Sourcing - Andrea Saltarello
1. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
The Fine Art of Time Travelling:
implementing Event Sourcing
Andrea Saltarello
Solution Architect @ Managed Designs
http://twitter.com/andysal74
andysal@gmail.com
3. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Demos.About();
All demos (but one) are based on Merp, a GPL’ed
Micro ERP I developed (and still do, to an extent) as
the companion project for my book.
It’s ”free as in speech”, so:
1. Download & unzip it
2. Open the .sln file in Visual Studio
3. Run Update-Database (x2)
4. Enjoy time travelling
8. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
It really became clear to me in the last couple of years that
we need a new building block and that is the Domain Event.
[Eric Evans]
An event is something that has happened in the past.
[Greg Young]
A domain event … captures the memory of something
interesting which affects the domain
[Martin Fowler]
9. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Instead of focusing on a system’s last known state, we might
note down every occurring event: this way, we would be able
to (re)build the state the system was in at any point in time
just replaying those events
To cut a long story short: we’d end up
recording an event stream
Event Sourcing in a nutshell
JobOrderStarted InvoiceIssuedJobOrderExtended JobOrderCompleted
10. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
What’s an event, anyway?
The (immutable) composition of:
• A (meaningful) name
• (Typed) Attributes
InvoiceIssued
DateOfIssue
Customer
Price
ProjectStarted
DateOfStart
ProjectId
ProjectCompleted
DateOfCompletion
ProjectId
ProjectRegistered
DateOfRegistration
DateOfEstimatedCompletion
ProjectId
CustomerId
Price
12. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Events vs. Relations
INSERT INTO X (M, L, G) VALUES (1, 0, 1)
UPDATE X SET M=X, L=Y … WHERE …
UPDATE X SET M=42 … WHERE …
UPDATE X SET J=K … WHERE …
INSERT JobOrderStarted () VALUES ()
INSERT JobOrderExtended () VALUES ()
INSERT InvoiceIssued () VALUES ()
INSERT JobOrderCompleted () VALUES ()
Although replaying a DBMS transaction log or adopting
a temporal database would allow to restore a specific
system state, we would miss the reason behind every
occurred change nonetheless
13. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Still, my users are more interested in knowing a job
order’s balance or whether an invoice has been paid.
(cit.)
That is, we need a way to produce an entity state
Event Stream vs. «My application»
14. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Event Sourcing <3 DDD
DDD’s Aggregates provide a convenient way to encapsulate event
management
Aggregate: A collection of objects that are bound together by a root
entity, otherwise known as an aggregate root. The aggregate root
guarantees the consistency of changes being made within the
aggregate.
[Wikipedia]
An aggregate is responsible for:
• encapsulating business logic pertaining to an “entity”
• generating events so to have them available for saving
• replaying events in order to rebuild a specific state
16. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Aggregates vs. Events vs. Repos
var aggr = repository.GetById<TAggr>(id); //Triggers events replay
aggr.DoSomething(); //Biz logic + events
repository.Save(aggr); //Updates the event stream
Repository: Mediates between the domain and data mapping
layers using a collection-like interface for accessing domain
objects. [DDD]
18. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Still², my users are more interested in knowing a job
order’s balance or whether an invoice has been paid.
Quickly.
Ways to achieve that:
• Snapshots can help
• CQRS to the rescue: let’s have a database storing the usual «last known system
state» and use it as the read model
Event Stream vs. «My application»
20. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Enter CQRS
Acronym for Command Query Responsibility
Segregation
Basically, ad hoc application stacks for both writing
and reading:
• “Command” stack writes events and snapshots
• “Read” stack reads from eventually consistent, reading purposes
optimized database(s)
22. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
CQRS/ES in a nutshell
1. Application sends a command to the system
2. Command execution might alter the system’s state and
then raise events to state success/failure
3. Events are notified to interested subscribers (a.k.a.
handlers), such as:
• Workflow managers (a.k.a. «Sagas») which could execute more
commands
• Denormalizers, which will update the read model database
Note: command/event dispatch/execution will usually be
managed by a Mediator («bus»)
23. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
CQRS/ES at a glance
Application
Layer
Snapshots
Event store
Read stack
Domain Layer
Ad-hoc DBHandlers
Command Event Data
Handlers
Model ServicesB
U
S
25. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
On a technology side…
An effective CQRS/ES implementation usually relies
on 2 structural pillars:
• A bus (to be used as the Mediator)
• An application framework (implementing event sourcing
plumbing)
Should we build them or should we buy them?
26. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
A bus! A bus! My Kingdom for a bus!
Although building a simple bus might be feasible (and
tempting as well ), 3°-party products (e.g.: MassTransit,
NServiceBus, Rebus, …) provide much-needed features such
as:
• Fault tolerance
• Scalability
• Events’ scheduling
27. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
The bus: a couple of options
Masstransit
https://www.nuget.org/packages?q=Masst
ransit
NServiceBus
https://www.nuget.org/packages?q=NServ
iceBus
Rebus
https://www.nuget.org/packages?q=Rebus
• FOSS
• Both On-Premises & cloud
• Events scheduler
• Both On-Premises & cloud
• CQRS-friendly API
• FOSS
• Events scheduler
• Both On-Premises & cloud
• CQRS-friendly API (similar to
NServiceBus’)
28. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Application Frameworks
MementoFX
https://www.nuget.org/packages?q=MementoFx
NEventStore + CommonDomain
https://www.nuget.org/packages?q=NEventStore
• Time travel
• Alternative timelines
• DDD/CQRS/ES Full stack
• Both On-Premises & cloud
• FOSS
• DDD/CQRS/ES Full stack
• Both On-Premises & cloud
29. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
Time Travelling… «Fringe» style
What if we could manage events occurring in parallel,
alternative timelines?
31. @ITCAMPRO #ITCAMP16Community Conference for IT Professionals
[DDD] Domain Driven Design, Eric Evans , Addison-Wesley
[NAAE] Microsoft .NET: Architecting Applications for the
Enterprise (2° ed.), Andrea Saltarello & Dino Esposito,
Microsoft Press
[MERP] Merp, https://naa4e.codeplex.com/
Bibliography