Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event Sourcing: Events that trigger others & rebuilding state

I'm struggling to get my head around what should happen when rebuilding the model by replaying events from the EventStore, in particular when events may trigger other events to happen.

For example, a user who has made 10 purchases should be promoted to a preferred customer and receive an email offering them certain promotions.

We clearly don't want the email to be sent every time we rebuild the model for that user, but how do we stop this from happening when we replay our 10th PurchaseMadeEvent ?

like image 580
Kirschstein Avatar asked Sep 05 '11 20:09

Kirschstein


People also ask

What is event sourcing example?

Good examples for Event Sourcing are version control systems that stores current state as diffs. The current state is your latest source code, and events are your commits.

Which is a main benefit of event sourcing?

Event sourcing has several benefits: It solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes. Because it persists events rather than domain objects, it mostly avoids the object‑relational impedance mismatch problem.

What is the event sourcing pattern?

The Event Sourcing pattern defines an approach to handling operations on data that's driven by a sequence of events, each of which is recorded in an append-only store.


2 Answers

Events chaining can be very tricky and easily run out of control, so I'd avoid it as much as possible. For example in the scenario you're describing I'd raise a UserPromotedEvent (maybe even using the PromoteUserCommand), however I wouldn't consider actual/physical sending of an email as part of my domain. Instead I would create additional handler/denormalizer for UserPromotedEvent that would register the need of sending the email with some additional checks quite possibly. After that another process would gather information of not yet processed emails and send them. This approach would mitigate the problems that might occur with not fully accessible/scalable email gateway.

In more general - the need of events chaining very often indicates that you should consider implementing a Saga for the process.

like image 137
kstaruch Avatar answered Oct 19 '22 18:10

kstaruch


You should not raise event from event handler - just don't do it! You should use sagas instead.

In your case, saga subscribes for PurchaseMadeEvent and issues PromoteCustomer COMMAND, which causes to happen CustomerPromoted event. Again, there is another saga that subscribes for CustomerPromoted event and sends SendEmailToPromotedCustomer command. When you are replaying events - just don't subscribe saga for CustomerPromoted event.

This is all about the difference between command and event. It is important to understand it. Events tell what already has happened, commands tell what will happen.

like image 45
xelibrion Avatar answered Oct 19 '22 18:10

xelibrion