Andrew Rea - For July 2010
-
A rough mapping of a CQRS Implementation through a Sequence Diagram
So I am currently looking at an example application implementing CQRS by Mark Nijhof. You can find and check out the example application at github, http://github.com/MarkNijhof/Fohjin
This for me is a real example of where reading code improves your own outlook and skills in coding. I feel this application is a superb example of good Architecture and encapsulates all the correct principles and practices which are encouraged and implemented through out the industry. To try and understand how it all fitted together I thought I would just jump in and create a rough sequence diagram. I used some excellent free software to create the diagram called Violet Uml Editor.
Please click to see a larger version.
In a previous post I mistakenly used the word event when I actually should have written command. After studying the code base to construct the above diagram I can now make the following assumptions about it and in turn try to describe the work flow.
- On Application Start
- All Commands and CommandHandlers are resolved and added to the MessageRouter
- All Events and EventHandlers are resolved and added to the MessageRouter
- Client creates and publishes a command to the Bus
- The message router loops through all the command handlers and invokes each wrapped inside a Transaction handler.
- The Transaction Handler gets or adds the DomainObject through the DomainRepository which indirectly gets Registered For Tracking inside the UnitOfWork.
- When the Command Handler is executed, it is done so inside a wrapper. This also invokes the Commit method on the UnitOfWork.
- The UnitOfWork will then loop through each of the Domain Objects (Event Providers) it has Registered For Tracking and do the following:
-
- Save the Domain Object (Event Provider) through the Domain Event Storage.
- Publish the events which have occurred for said Domain Object to the Bus
- The Domain Objects which are Registered For Tracking are then cleared.
- When the Events are published to the Bus, the Message Router will now loop through the EventHandlers it has for each event and invoke each.
- The Event Handlers will then interact with the Reporting Repository and update the Reporting Data Store accordingly.
This is not exact by any means as you will probably pick up on immediately, but I am gradually getting my head around what is happening with this application and CQRS in general, and liking more and ore as I go :) .
With the above in mind and the fact that I want to introduce the Service Layer using Agatha, I am thinking that the RequestHandlers in Agatha will have either of the following two responsibilities:
- Create a publish a Command to the Bus
- Interact with the Reporting Repository.
1.) Will deal with all the write requests obviously and 2.) with the read ones. Once this is done, I can see a nice layer where the client is shielded from the CQRS and literally just executes Requests as normal.
Cheers for now,
Andrew
Posted by Andrew Rea on July 11 at 9:58 AMComments (0)
- On Application Start
-
CQRS and Replaying state events from a snapshot
Still reading the blog posts from Greg Young and derived works and one of the points which I have just got my head through is the scenario where you may have 100,000 + events for a particular object. Basically, to obtain the state for said object you need to load the aggregate from the persistence layer, and the only information you have to build up the object are the commands which were executed, so you have to replay them. Replaying 100,000+ events every time you need to load up an aggregate would be slow so the Memento pattern is used. This means that you can query the last Memento of the object and replay only the Commands that were executed after that time.
I really like the idea of this way of thinking. Another point that was made is that, say you get a bug in your system. Remedy for such bug should come in the form of a Command. When I read this, i kind of tilted my head slightly whilst reading it, but it makes perfect sense.
In previous blog posts I have mentioned that I use Agatha library on my service layers and with this I was thinking that I already have the entry point for the Command Handler. Of course I have the write and read requests so I would have to make sure that the write request handlers dealt with the domain model, where as the read request handlers dealt with the traditional DAO Repositories and Finders.
IDEA : I can imagine that the types of UIs which could evolve from this style of architecture will be sweet. I am picturing an interface where you could simply find an object from the read store, and when you select this object the UI will then load in the object from the transactional write store and possibly a nice timeline look-a-like with a property grid display of the object parallel to it. You could have a slide on the timeline and each time you changed the value of the slider, you could see the information in the property grid update.
Posted by Andrew Rea on July 09 at 11:08 AMComments (0)
-
Having a think about CQRS and Eventual Consistency
I 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:
Posted by Andrew Rea on July 07 at 4:07 AMComments (0)