Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event Sourcing with Side-Effects

I'm building a service using the familiar event sourcing pattern:

  1. A request is received.
  2. The aggregate's history is loaded.
  3. The aggregate is rebuilt (from its history).
  4. New events are prepared and the aggregate is updated in response to the incoming request from Step 1.
  5. These events are written to the log, and are made available (published) to any subscribers.

In my case, Step 5 is accomplished in two parts. The events are written to the event log. A background process reads from the event log and publishes all events starting from an offset.

In some cases, I need to publish side effects in addition to events related to the aggregate. As far as the system is concerned, these are events too because they are consumed by and affect the state of other services. However, they don't affect the history of the aggregate in this service and are not needed to rebuild it.

How should I handle these in the code?

Option 1- Don't write side-effecting events to the event log. Publish these in the main process prior to Step 5.

Option 2- Write everything to the event log and ignore side-effecting events when the history is loaded. (These aren't part of the history!)

Option 3- Write side-effecting events to a dummy aggregate so they are published, but never loaded.

Option 4- ?

In the first option, there may be trouble if there is a concurrency violation. If the write fails in Step 5, the side effect cannot be easily rolled back. The second option write events that are not part of the aggregate's history. When loading in Step 2, these side-effecting events would have to be ignored. The 3rd option feels like a hack.

Which of these seems right to you?

like image 562
Charles R Avatar asked Jan 04 '16 23:01

Charles R


2 Answers

Name events correctly

Events are "things that happened". So if you are able to name the events that only trigger side effects in a "X happened" fashion, they become a natural part of the event history.

In my experience, this is always possible, because side-effects don't happen out of thin air. Sometimes the name becomes a bit artificial, but it is still better to name events that way than to call them e.g. "send email to that client event".

In terms of your list of alternatives, this would be option 2.

Example

Instead of calling an event "send status email to customer event", call it "status email triggered event". Of course, if there is a better name for the actual trigger, use that one :-)

like image 121
theDmi Avatar answered Sep 22 '22 16:09

theDmi


Option 4 - Have some other service subscribe to the events and produce the side effects, and any additional events related to them.

Events should be fine-grained.

like image 42
KarlM Avatar answered Sep 19 '22 16:09

KarlM