NH ProfArchitectural Overview
I am pretty fond of the way NH Prof is architected. At a very high level, it looks like this:
The first part isn’t really that interesting, the main challenge is to get the data from your application to the profiler in as speedy and performant way as possible. We are using a binary protocol based on Protocol Buffers with TCP Sockets as the communication mechanism.
Next we have the listener and the message processors. That is where a lot of the magic actually happens, we do first level analysis on the incoming log messages and transform them into higher level concepts. At this point, we are only dealing with a single message, we have no overall picture, but a lot of work is actually happening at this layer.
It is there that I normalize the differences between all the NHibernate versions that I support and make sure that the other layers work on a common object model.
The next stage is the model building, where I am actually taking all the information and start putting it together, it is there where concepts such as sessions, and statements in session start making sense, it is there that I actually apply analytics to provide you with the alerts. It is a pretty complex piece of code, taken together, but each individual part is pretty simple.
Next, we have the view model, which is another representation of the model in a format that is applicable for showing to the user, I have spoke before about moving from a push to a pull model, in order to allow the UI to remain performant. That has been one of the major challenges in that area. Well, that and making sure that we have good UX.
The interesting part about this architecture is that a new feature is usually something that happen either in the listeners and the model building (when it match the current model that we have) or a vertical slice across the entire layer, when we need to express some new concept.
More posts in "NH Prof" series:
- (09 Dec 2010) Alert on bad ‘like’ query
- (10 Dec 2009) Filter static files
- (16 Nov 2009) Exporting Reports
- (08 Oct 2009) NHibernate Search Integration
- (19 Aug 2009) Multiple Session Factory Support
- (07 Aug 2009) Diffing Sessions
- (06 Aug 2009) Capturing DDL
- (05 Aug 2009) Detect Cross Thread Session Usage
- (22 May 2009) Detecting 2nd cache collection loads
- (15 May 2009) Error Detection
- (12 May 2009) Queries by Url
- (04 Feb 2009) View Query Results
- (18 Jan 2009) Superfluous <many-to-one> update
- (18 Jan 2009) URL tracking
- (10 Jan 2009) Detecting distributed transactions (System.Transactions)
- (06 Jan 2009) The Query Cache
- (05 Jan 2009) Query Duration
- (24 Dec 2008) Unbounded result sets
- (24 Dec 2008) Row Counts
Comments
Oren, I can't get something...
at very high level you have low level messages processor...
something must have been architected real baaaad =)
cowgaR,
That is because low level message processing have a very important role in the overall architecture.
Low level msg processing simply means the part that process the raw data from NHibernate
ah, it was a joke ;p
never try to "escape" your highly technical role?
One question I would ask: Can you give an example of a "vertical slice" as you put it, and why, when making said vertical slice, you don't have jagged lines reaching out? I'm assuming that's what you mean, but could have taken the metaphor incorrectly, so correct me if I'm wrong.
I imagine something like that would be a new feature that you want to define which the UI and the model do not necessarily support.
Kyle,
A good example of that would be changing the way that we are showing query duration, instead of just showing overall duration, we want to show time in db and time processed by NH.
That means that we have to read the new data from the profiled application, attach them to the right place in the model, and actually change both the backend model and presentation model to contain both data items.
Cool. To me, that implies to the untrained eye that it's highly coupled - "You shouldn't have to change every single layer in order to display new data!" In my view, though, that seems like a really stupid statement. I've never seen a single program where that senseless platitude worked out. I've seen people try, and it became so complicated that they themselves could not make a change when it was necessary, though!
I didn't have any other place to write this right now, but it's not terribly on topic. What is the point of an abstraction if there is nothing abstract about it, or in other words an object that does not have any functions which can be overridden?
Comment preview