Replaying Events

Jun 17, 2010 at 7:16 PM

With Ncqrs, what is the best way to replay events?

I want to replay the event stream in order to recreate/repopulate my readmodels.

Are there any gotchas that I should be aware of?

The ones I can think of are:

* The readmodel would need to be truncated before running the replay?

* What about events that should happen only once? For instance, if I have a OrderCreated event, and a handler on that event that issues a SendCustomerOrderCreatedConfirmationEmail, how do I ensure that this command is not issued when doing a replay?

Jun 17, 2010 at 10:10 PM
Edited Jun 17, 2010 at 10:12 PM

Depends why you are replaying them and the effect it has on the system, it is something I've been pondering myself for a while now as everyone says you can just replay the events but don't say how. I think replaying events has to be handled on a case by case basis, but here are some of my thoughts:

  1. You've introduced a new de-normalizer or external system and wish to replay the events to create new de-normalized data, this does not effect existing tables or structures. For this, you could just create a temporary stub that reads the events and runs them through the new de-normalizer or publishes them to the external system. Should be able to process this straight into an existing database without disruption.
  2. Fixed a bug in the way an existing event was being handled. This will require rebuilding the affected tables. Depends on the nature of the problem, you might be able to create a temporary de-normalizer just to fix the error, or you might need to start with a blank table and re-build it all.
  3. Need to introduce a new de-normalizer that interacts with existing data. Same as before, but you'll need to process all the event streams that affect that data.

If you do need to re-build a table then how that works depends on the system and the options are:

  1. Shut down the application whilst the table is re-built.
  2. Rebuild directly into the current database whilst the application is running, accept the data will be incomplete or out of date during this time.
  3. Leave the old database running as normal, with the erroneous and processing events as normal. Rebuild the new data in a second copy of the data. Once the new copy has finished building switch the clients over to use the new database and remove the old one. This might be easier if you have a pub/sub for events, as you can add the new database as a subscriber but have it disabled whilst re-building, then when you are ready to switch the new events will be sat in the queue ready to pick up and you can just remove the sub for the old database.

The external systems: If you're using a stub program just to replay the events you simply don't connect them to the bus, if you do want to build a replay system in to the service itself then it should be left to the services that deal with the external systems to check if the current context is in replay mode or not. The replay status should really be part of the current context or unit of work.