Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event sourcing chaining events

I'm implementing a bounded context using event sourcing but have come across a problem. Say I'm modelling a game of soccer, and I'm interested in both the individual goals scored (who scored them etc) and the overall score. So if I have a Match aggregate root I ideally want events raised called GoalScored and ScoreChanged. The reason I want the score explicitly stated from the domain like this is that I don't want lots of different listeners and possibly other bounded contexts all computing the same thing.

This seems simple, but: the Match object has a Goal() method that adds a new goal. In the spirit of event sourcing this doesn't directly mutate Match state, but raises a GoalScored event that is handled within the Match which then mutates the state (as well as the event being pushed out to denormalizers). So in terms of raising a ScoreChanged, the score hasn't actually changed until the GoalScored event has been handled, so do I raise another event in response to that event (ScoreChanged), effectively chaining the events? I don't think so, for a start when an aggregate root is reloaded from the event store lots of extra events are going to be created each time in response to each GoalScored.

I also thought about working out what the score would in the command handler that raises GoalScored, sort of a 'what if' situation. Then I could raise both events in the command handler. I'd really rather not do that though - it just doesn't seem 'right'. Working out the score is simple enough for soccer, but other games (cricket for example) requires more work.

I could put both the goal and the score in the GoalScored event, which is fair enough, but again it doesn't seem right - the score has got nothing to do with a GoalScored event per se.

All the examples used when discussing event sourcing seem to use the eCommerce Customer/Order domain, and I've never seen a similar case as this.

Does anyone have any experience dealing with situations like this?

Thanks

like image 424
user303754 Avatar asked Jan 15 '13 08:01

user303754


People also ask

What is the difference between event-driven and Event Sourcing?

Event Sourcing is about using events as the state. Event Driven Architecture is about using events to communicate between service boundaries.

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.

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.

What is the difference between Event Sourcing and CQRS?

CQRS is implemented by a separation of responsibilities between commands and queries, and event sourcing is implemented by using the sequence of events to track changes in data.


2 Answers

The choosing of clean domain events, just like other modeling, should result in concepts that are mirrored in the domain. You say "the score has got nothing to do with a GoalScored event per se". But it does. In soccer, the only way a score can change is if a goal is scored. Though, goals can be taken back, e.g. via offsides calls or other penalties. It's not clear whether you want to model this or not.

It is common for a domain method to emit multiple events at once. A good framework will make it easy to consider them as a bunch, e.g. as a single commit. Why not emit both a GoalScored and ScoreChanged event?

You may also want to consider whether this domain has any commands at all. The soccer match itself is the system of record. The events that come from the match are a record of history already. Are you perhaps just writing a system which processes streams of events into streams of more events?

like image 96
Sebastian Good Avatar answered Oct 22 '22 18:10

Sebastian Good


One thing that often helps when thinking about event sourcing is to notice your tense - you say StartMatch, but in an event sense it's actually the event MatchStarted.

As for the ScoreChanged, are you consuming this event outside of the Match? If not, the Score should be the only part publically accessible, and the GoalScored event simply mutates this. This holds CQRS in a minor way (how I get the score doesn't depend on how I change it). Score can then internally hold a state, or can replay all the GoalScored events to arrive at a number each time it's called. The 'feel' of properly designed event-sourced solutions can always regenerate any state from the events.

Now, if the ScoreChanged needs to alert other parts of your system (a player ranking, for instance), you can either multi-cast the event to different roots, or you might need to refactor your design. In this case, do you want to update players in real time, or only after a match is complete?

like image 29
Mathieson Avatar answered Oct 22 '22 20:10

Mathieson