Upload
codemotion
View
198
Download
0
Embed Size (px)
Citation preview
25 NOVEMBRE 2016
The Fine Art of Time Travelling: implementing Event Sourcing
AndreaSaltarelloSolutionArchitect@Managed Designs
https://twitter.com/andysal74
There’s nosilverbullet
Not the waytoimplement Event Sourcing,but a working waytodoit nonetheless
Demoapp available onGithub (GPL3),BTW
ItreallybecamecleartomeinthelastcoupleofyearsthatweneedanewbuildingblockandthatistheDomainEvent.
[EricEvans]
Aneventissomethingthathashappenedinthepast.[GregYoung]
Adomainevent…capturesthememoryofsomethinginterestingwhichaffectsthedomain
[MartinFowler]
Insteadoffocusingonasystem’slastknownstate,wemightnotedowneveryoccurringevent:thisway,wewouldbeableto(re)buildthestatethesystemwasinatanypointintimejustreplayingthoseevents
Tocutalongstoryshort:we’denduprecordinganeventstream
Event Sourcing inanutshell
JobOrderStarted InvoiceIssuedJobOrderExtended JobOrderCompleted
What’s anevent,anyway?
The(immutable)composition of:• A(meaningful)name• (Typed)Attributes
InvoiceIssued
DateOfIssue
Customer
Price
ProjectStarted
DateOfStart
ProjectId
ProjectCompleted
DateOfCompletion
ProjectId
ProjectRegistered
DateOfRegistrationDateOfEstimatedCompletionProjectIdCustomerIdPrice
Events vs.Relations
INSERTINTOX(M,L,G)VALUES(1,0,1)UPDATEXSETM=X,L=Y…WHERE…UPDATEXSETM=42…WHERE…UPDATEXSETJ=K…WHERE…
INSERTJobOrderStarted VALUES()INSERTJobOrderExtended VALUES()INSERTInvoiceIssued VALUES()INSERTJobOrderCompleted VALUES()
Although replaying aDBMSevent logoradopting atemporal databasewould allow torestore aspecific system state,we would missthereason behind every occurred change nonetheless
Still,my users aremoreinterested inknowing ajoborder’s balanceorwhether aninvoice has been paid.(cit.)
That is,we need awaytoproduceanentity state
EventStreamvs.«Myapplication»
Event Sourcing <3DDD
DDD’s Aggregates provide aconvenient waytoencapsulate eventmanagement
Aggregate:Acollection ofobjects that arebound together byaroot entity,otherwise known as anaggregateroot.Theaggregateroot guarantees theconsistency ofchanges being madewithin theaggregate.
[Wikipedia]Anaggregateis responsible for:• encapsulating businesslogic pertaining toan“entity”• generating events tohave them available forsaving• replaying events inorder torebuild aspecific state
Aggregates vs.Events vs.Repos
var aggr =repository.GetById<TAggr>(id); //Triggers [timetravelling capable]event replayaggr.DoSomething(); //Domainlogic +events raisingrepository.Save(aggr); //Updates theevent stream +events dispatching
Repository:Mediates between thedomainanddatamapping layers using acollection-like interfaceforaccessing domainobjects.[DDD]
Still²,my users aremoreinterested inknowing ajoborder’s balanceorwhether aninvoice has been paid.Quickly.
Waystoachieve that:• Snapshots canhelp• CQRStotherescue:let’s have adatabasestoring theusual «lastknown systemstate»using it as aread model
EventStreamvs.«Myapplication»
Enter CQRS
Acronym forCommand QueryResponsibility SegregationBasically,adhocapplication stacks forboth writing andreading:• “Command”stack writes events andsnapshots• “Read”stack reads fromeventually consistent,reading purposesoptimized database(s)
CQRS:the“Read”sideoftheForce
Asabusinessunitmanager,Iwanttocollectcreditsduetounpaidoutgoinginvoices #ubiquitouslanguage #nuffsaid
CQRS/ESwise,this user storycould beimplemented bymeans ofthefollowing real worldC#code:
Database.OutgoingInvoices..PerBusinessUnit(businessUnitId).ExpiredOnly().Select(i=>new{InvoiceNumber =i.Number,CustomerId =i.Customer.Id}).AsParallel().ForAll(i=>bus.Send(newCollectDebtCommand(i.InvoiceNumber,i.CustomerId)));
CQRS/ESinanutshell
1. Applicationsends acommand tothesystem2. Command execution might alterthesystem’s stateandthen raise
events tostatesuccess/failure3. Eventsarenotified tointerested subscribers (a.k.a.handlers),such
as:• Workflow managers (a.k.a.«Sagas»)which could execute morecommands• Denormalizers,which will updatetheread modeldatabase
Note:command/event dispatch/execution will usually bemanaged byaMediator(«bus»)
ApplicationLayer
Snapshots
Eventstore
Readstack
DomainLayer
Ad-hocDBHandlers
Command Event Data
Handlers
Model ServicesBUS
CQRS/ESataglance
TimeTravelling… «Fringe»style
What if we could manage events occurring inparallel,alternativetimelines?
Abus!Abus!Mykingdom forabus!
Although buildingasimple busmight befeasible (andtempting as wellJ),3°-partyproducts (e.g.:MassTransit,NServiceBus,Rebus,…)providemuch-neededfeaturessuchas:• Faulttolerance• Scalability• Workflowsupport• Events’scheduling
Grazie!
Contatti:
• https://twitter.com/andysal74• http://blogs.ugidotnet.org/pape• [email protected]