alaboudi
alaboudi

Reputation: 3413

Event Sourcing - Replaying Events

Imagine an event sourced system where there exists a consuming service that is subscribed to a certain Event A. Once this consumer detects Event A has been emitted in the network, it handles it somehow and dispatches its own Event B.

How would someone replay such a system. Before the replay, both Event A and Event B exist in the event store/database. If we replay Event A and Event B, would this not double count the dispatch of Event B (once being deduced from A and the other being replayed from our event store)? How do you go about replaying events in general when 1 event may cause a cascading chain of other dispatched events.

Upvotes: 5

Views: 2560

Answers (2)

Andreas Hütter
Andreas Hütter

Reputation: 3911

It is not really a form of replaying the events in the system so that each event is published again and triggers actions. It is more like rehydrating (reconstituting) aggregates from events which are stored in the event store.

The implementation could for instance involve a specific constructor (or factory method) of an aggregate that takes a list of the stored domain events related to the specific aggregate. The aggregate than simply applies those events to mutate its own state until the current state of the aggregate is reached.

You can take a look at such an implementation in Vaughn Vernons sample Event Sourcing and CQRS project iddd_collaboration. I directly referenced the implementation of a Forum Aggregate which is derived from Vaughn Vernon's implementation of an EventSourcedRootEntity.

You can look into the Forum constructor

public Forum(List<DomainEvent> anEventStream, int aStreamVersion) {
    super(anEventStream, aStreamVersion);
}

and the related implementations of the different when() methods and the base class functionalities of EventSourcedRootEntity.

Note: If there is a huge amount of events and performance issues are a concern during aggregate rehydration looking into the concepts of snapshots might also be of your interest.

Upvotes: 3

user18820619
user18820619

Reputation: 1

You're referring to what's called a "Saga Pattern" and in order to resolve it you need to make your commands explicit. This example helps to illustrate the difference between Commands and Events.

Events are the record of what happened. The are immutable, connected with an entity and describe the original intention of the user.

Commands are a request to do something, which may cause an event to be recorded. They can also cause 'real world' state changes outside of the event-sourced system, but in doing so they should cause an event that records the external change happened.

A few rules will resolve your conundrum:

  1. You cannot record an event without a corresponding command having executed. Every event was caused by a command.
  2. You cannot process commands until the event stream has 'caught up' to the present. Otherwise you are taking action on a partial replay of history.

Back to the Saga Pattern: In the Saga Pattern, events can lead to more commands. In this way, the system can progress based on a cascade of events and commands and execute a distributed workflow, choreographed by the relations between system state, commands generated, and further events generated.

In your case, as long as you wait for the full event stream to be replayed before issuing the next command, you can then prevent the duplicate cascading event by checking that the action has not already been done.

If event B already exists, there's no need to issue another command to generate event B again.

Upvotes: 0

Related Questions