Quick question, I've been digging into CQRS and Event Sourcing and there's one thing that I have not been able to find info on, what happens when your Write Service crashes and you need to start it back up? I understand how you can recover your Read Service by replaying the events, that makes sense to me. What I can't find information on is rebuilding the state of the Write Service.
In Event sourcing, the Write model is rebuild from its past events every time it processes a command. In DDD, the Write model is the Aggregate; I will refer to it as such. So, the algorithm is something like this:
- The client creates a command.
- The command arrives at an Application service; in some architectures this is called
the command handler.
- The command handler identifies the Aggregate's class for this command; it can be only one
- The command handler use a Repository to load the Aggregate's
- The Repository creates a new, empty Aggregate; it can use the
- The Repository loads all it's previous emitted events and it applies them one at a time and in the order they were emitted; for example, the Aggregate has an
applyEventmethod for each Event type; I use a convention to name the methods as
applyEventShortClassName, one for each event class/type; then it returns the Aggregate
- The command handler calls the appropriate method on the Aggregate; I use a convention and I name the methods as
handleCommandShortName(theCommandAsParameter)but other methods can be good.
- The command handler collects all the emitted events from the Aggregate and use the repository to append them to the stream of events for this Aggregate instance. Every instance of the Aggregate (i.e. for each ID) has a different stream of events.
- If a concurrency exceptions occurs, the entire process is retried from step 4.
The above algorithm may differ from one programming language to another, from one architecture to another, but the main idea is the same: the Write model is rebuilt from its event stream before every command.
What I can't find information on is rebuilding the state of the Write Service.
The same way - you read the persisted state back out of the book of record.
Event sourcing doesn't change the core idea that we are storing state that we use to recover if our transient data caches are lost (for example, by a shutdown).
The fact that we separate the models we use for reads from the models we use for writes doesn't change the principle idea of how do we initialize - we just have two things to initialize rather than one.
So it works the same way it would if we were reading persistent data out of a key value store, or out of an RDBMS. We just have this extra step in the middle where, having read the history out of the persistent store, we have to iterate over it to get to the "present" state.