The story on how I discovered, fell in love and abandoned Event Sourcing
This is a story with quite some drama, the discovery, the peak and the let down. To be honest, I discovered and used Event sourcing way before it was called event sourcing, and way before it was cool, or at least at that time, I had no idea that this will become such a hot topic.
It all happened about 7 years ago, I was a quite happy camper, achieving my “mid software engineer” title and was a awaiting this awesome new project were, for the first time will have a say in the software design (green field and stuff). Everything was looking just fine and dandy, the client was a top client, the software stack was up to us to pick, so yeah I was super hyped, that is, until I got the requirements…
I was super hyped, that is, until I got the requirements…
Apart from the usual stuff, there was one thing that, thus far, I haven’t ever done on a web based application nor ever seen being implemented, this thing was the ability to audit everything (including data access) and undo any changes done on the domain objects.
At this point, I kind of understood why other people with more seniority didn’t want to work on this, this was looking to be quite a big undertaking to implement, keep in mind this was something about 2010 – 2012, nosql was a kind of an idea more than an actual product, and cloud wasn’t yet in the picture and we were still using .net 3.5 and 4 at that time and phones back than were upgrading from Android 1.6 to 2.1.
But I digress, back to the story. Now that we build a better temporal awareness and a bit more context, let go into the more depth. As I said, I was a seen as a “promising” young engineer back than, and this was the first project with this new client a lot of eye were on me, and a lot of pressure, as you may or may not know, if you are working in a consulting / services context, the first project usually makes or brakes a partnership. So yeah, the stakes were high.
So how did we managed to pull this of ? Well, after endless discussion with my Team Lead / PM and a few other people around, who mostly had their experience in embedded C and low level UNIX development, and doing some research on how desktop applications do this (mostly playing around in excel trying to figure it out), I came with this crazy idea of writing our software stack.
We will be using MVC instead of WebForms ( first revolutionary thing, back than ), and instead of the regular way of storing data ( CRUD based ) we will be storing ALL of the interactions with the back-end that touch the Domain objects in Journal tables. In order to give the users the ability to read the data in a “normal view” we would hydrate the journal entries for that specific id by selecting them and applying all the changes one after the other, this way we would be able to know exactly who made what change, and also have versioned “domain objects” and we would be able to undo changes.
People seemed to like the idea, and gave me the green light, I was the only developer working on this full time with two other seniors who I could ask help from on very specific issues.
So off to the races, I started implement this to the best of my abilities back than, everything was going great until I realized than my great design had this small performance issue, on a very small and not very frequently used page, the List View … I’m not going to lie, this was baaaaddd… after letting the others know about this, they gave me a few days to fix this, or they would take the project away from me, and rebuild it with a different team using “industry standard” patterns.
I’m not going to lie, this was baaaaddd…
As you could imagine, this scared the life out of me, but instead of despair I started thinking on how I could figure the perfect solution to this problem, because, I really liked the idea of this journaling the changes… So, as you might think right know this is obvious, back than, not so much, I wasn’t aware of Greg Young and his push of ES, so yeah, back to the story, so I came with this crazy “database memoization” idea.
How did this work ? Glad you asked. Well basically the way this worked was the following, on each “change” a user would make to a domain object, after we would save the “change” in the journal, we would call this memoization component ( I think we called it “[DomainType]MemoizationManager”, in those days most classes were managers :D) to run, this component would go through each of the events of a specific ID, and build the state for it, as before, but this time, instead of returning it it would save it in a “classic” database table, also, this entity also had two columns to keep track of the version and id of the last processed event so it would require to go through all of them on each change. Than, we set up MVC to display the list and detail view based on this table. Also, in order to minimize the chance that a user would see old data after a “change was made”, after the edit view was submitted, we would redirect them to a page that said that the “change was successful” and provided links to the detail view and list view ( I know, but UX wasn’t a thing back than).
Yep, this worked like a charm, the day was saved! (and I continued to work there for about 5 more years). But this was not all, this “db memorization” basically was like a gateway drug, and one of the best things since sliced bread, because it opened the way to building backing tables for highly specific reports that otherwise would take tons of ram and cpu to process.
Now, if you are even remotely familiar with “modern” event sourcing you will basically recognize that was I used was, CQRS ( acknowledging the changes via commands, having a different read model, although used the same DB), Event sourcing with Stream per type, since DBs don’t usually like to have dynamic tables, and projections ( DBMemoization ). Just for the record, we also used event snapshots after about 200 events ( at the end as an optimization), and cross domain object memoizations for the reports and the dashboard.
Nobody in their right mind would build such a complex abomination.
The sad thing about this whole project was that, although it turned out to be success, both commercial and technically, the client was very impressed by the performance and machine requirements, every one I talked about this solution at that time and quite a lot after said that, this was crazy, nobody in their right mind would build such a complex abomination, and could have been build with nHibernate and some services and a lot of polymorphism. It didn’t matter that this solution was better in terms of performance and memory usage, it wasn’t the way .NET was developed. After hearing this a lot more times than I’d like to admit, I kind of buried the idea more or less like a highly specific one time thing, and haven’t discussed about it again.
To be honest, I still used some things I learned from that project, for example building “report tables” with data updates triggered on domain events. But most of the time I had to be quite sneaky when presenting others the concept.
That was until, a couple of years ago a discovered ,by mistake, on YouTube, a talk from a guy called Greg Young who, for years was pushing this cool new idea, Event Sourcing. I remember watching the whole talk without event flinching, and at the very end I got this very nice and fuzzy feeling of knowing that I’m not crazy, or at least not as crazy as other people thought, or there were others that noticed this cool way of doing things. Now I had somewhere where I could send people if they thought I wasn’t making a lot of sense, and more importantly someone with more notoriety, so yeah thanks Greg.
Well, I think, if there is a takeaway from this story, that would be, if you are presented an idea by someone, even with far less seniority than you, give it thought, and remember that especially in software development there are endless ways of achieving something. And more important, if you are going to disagree or give feedback, give constructive feedback / criticism don’t just shut them down.