Having a think about CQRS and Eventual Consistency
Posted in .NET, Agatha, C#, CQRS by Andrew Rea on 7/7/2010 4:07:42 AM - CSTI have been watching and reading a few blogs and videos recently from various sources including Udi Dahan and Greg young and other blogs which have been based on those works. I am getting my head around CQRS and the different way of thinking which arises when following an Eventual Consistency approach.
One of things which I really like is the way which the write store is constructed from commands which build up a transaction log related to objects. For example I could replay a set of transactions to build up an object for a certain point in time or all the way to current state.
The whole point of CQRS (Command Query Responsibility Segregation) is to separate the writes from the reads, and making a write does not immediately change what is read. This is where the Eventual Consistency comes in. When a write command is processed, it will emit events which describe the changes which have occurred inside the write store, and it is the responsibility of the read stores to subscribe to these change events and update their read store appropriately. One way of thinking about the read store is as a reporting data store. The read store should structure and store its data in a way which is optimized for data retrieval, i.e. denormalized to the hilt.
Testing
Whilst watching the video of Greg Young on CQRS and his implementation I heard a short part which I really liked and that was related to testing. Using the BDD way of thinking (Given When Then) he explained that:
- Given a context (Forum)
- When a command is sent (CreateForum)
- Then events are raised (ForumCreated, UserForumCountChanged, ForumCategoryChanged).
A similar approach could easily be attained from an Arrange, Act and Assert approach but I do like the Given, When, Then approach.
So what he was saying is that from one command executed against the data store may result in one or more events being raised to describe what changes have taken place. This means that the events simply contain state, as the logic which was required to build such state has been handled inside the domain model. The read store simply has to store the data which it reads from the events. There should be no business logic occurring on the read databases. The fact that an entire system could be built in this manner promotes testability in many ways, and also indication of whether the system is meeting business requirements. Accepting testing would be stream lined and simplified with this approach as we can see the direct results of executing commands.
SIDENOTE: Whilst writing this a really obvious and simple idea came into my head and that was having the transaction log serialized in JSON format. I know it is simple but I am thinking that it would be really cool seeing the applications of storing the log in such a format as opposed to binary.
Integration with Service Layer and Agatha
I was thinking about integration with a service layer and how I should implement it. From my first pass I would say that it is clearly visible where each part should fit in and more than that it guards the client from the internals of what is happening. From the client I can send read and write requests to the same service, but it is at the service layer where I would execute the commands. For the service layer I use a library called Agatha and one of the components of this library is being able to send OneWayRequests which fits in nicely with the eventual consistency approach.
Going Forward
There are a couple of frameworks out there currently for CQRS in .NET including AgrCQRS which I have had a look at and it looks really good. You can read more and have access to a few valuable resources on CQRS with the following link : http://jwbs-blog.blogspot.com/2010/03/c-cqrs-framework-agrcqrs.html .
One of the topics I am currently looking into more is where you can build up an object using a partial selection of the transaction log,
Cheers for now,
Andy
References:
Comments
None.