<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.abdullin.com/~d/styles/itemcontent.css"?><!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Mon, 06 Feb 2012 11:16:51 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><title type="text">Rinat Abdullin on Lokad Shared Libraries</title><subtitle>Journal</subtitle><id>http://abdullin.com/journal/</id><link rel="alternate" type="application/xhtml+xml" href="http://abdullin.com/journal/" /><updated>2012-02-06T11:16:21Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.11.81 (http://www.squarespace.com/)">Squarespace</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.abdullin.com/Shared-Libraries" /><feedburner:info uri="shared-libraries" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry><title>People Don't Think in Tables</title><category term="Lokad" /><id>http://abdullin.com/journal/2012/2/5/people-dont-think-in-tables.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/a6LcleWTJeo/people-dont-think-in-tables.html" /><author><name>Rinat Abdullin</name></author><published>2012-02-05T12:14:26Z</published><updated>2012-02-05T12:14:26Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Within the last few years I've seen major change in UI approaches in the systems I build. The change is caused by a shift from relational databases as persistence to something that does not require an SQL server (or DB server at all). &lt;/p&gt;

&lt;p&gt;Take a look at this old UI of mine. It's pretty powerful (huge amount of buttons proves that), is intuitive for geeks and scary for normal people. &lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/02/2012-02-05-grid-ui.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;What's more curios, this UI is shaped by the relational persistence model that was created in mainframe days, when storage was expensive, memory even more so, and data had to be heavily normalized. However, technology has advanced slightly since then, and we no longer need to fit our UIs to something that is so spreadsheet-like. We can prevent user from overexposure to underlying data complexity, especially when data itself is simple, but just happens to be stored in a computer-optimized way.&lt;/p&gt;

&lt;p&gt;Think of it again. &lt;strong&gt;We turn UI experience of users in sudoku game just because we know how to store data in a way that was good 20 years ago&lt;/strong&gt;. No wonder Apple is making so much money - at least they don't try to turn every UI into spaceship control panel:&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/02/2012-02-05_183201.png?__SQUARESPACE_CACHEVERSION=1328445201388" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;People don't think with tables&lt;/strong&gt;. They would prefer something that is more simple, even if it does not benefit from a fancy styled UI framework. Something that does not involve solving &lt;a href="http://en.wikipedia.org/wiki/Sudoku"&gt;sudoku puzzle&lt;/a&gt; every time you need to find a simple answer to your question or do your job.&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/02/2012-02-05-facebook-ui.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;or where we have the most simple way to search complex structured info, as patented and proven to be useful by google:&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/02/2012-02-05-search-ui.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;It is surprising, how &lt;strong&gt;underlying technologies affect what we build with them&lt;/strong&gt;, is not it?&lt;/p&gt;

&lt;p&gt;As you can guess, first 2 screenshots depict UI that runs on some sort of SQL, while the other UIs were influenced by a simple NoSQL storage model (to be precise: CQRS/DDD+ES model that uses for UI persistence blobs for cloud persistence and plain files for on-premises deployments). &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;BTW, I know that quite a lot of people are using Lucene to provide full text search capabilities for their read models. However in the simplest case (esp. with cloud deployments), it's easier to write a few lines of code as opposed to dealing with one more dependency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another side effect is that with the change of underlying tech from SQL (and more importantly - thinking model), there is &lt;strong&gt;less need to resort to data-aware UI frameworks&lt;/strong&gt; (mostly used on conjunction with desktop apps) in order to provide rich user experience. This allows to have web-based applications that don't force framework installations  (good luck with getting .NET or Java on all machines in some large organization with a lot of momentum) or complex upgrade routines (i.e. ClickOnce auto-update or automatic MSI updates).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I'm not talking about development simplicity and cloud-scalability - these come for free, and we don't really value things unless we struggle for them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obviously, as you can see from screenshots above, my UI skills are still below that of a kid with a box of &lt;a href="http://en.wikipedia.org/wiki/Crayon"&gt;crayons&lt;/a&gt; but lately &lt;a href="http://twitter.github.com/bootstrap/"&gt;Bootstrup&lt;/a&gt; and jquery have provided a really nice experience, especially, when you can reuse some great ideas and frameworks.&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/02/2012-02-05_cqrs-case-studies.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Wait, till we start getting into mobile experience with HTML5. It actually comes almost for free as well, since latest web layout frameworks provide a lot of mobile experience out-of-box.&lt;/p&gt;

&lt;p&gt;NB: In no way I'm implying that this second approach is anywhere near close to being reasonably simple. And it's obviously bad looking (especially UIs that I hack together), but I think this is going in the right direction. At least, less time is wasted on writing UI docs and providing support.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=a6LcleWTJeo:eqD1vMxmWKQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=a6LcleWTJeo:eqD1vMxmWKQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=a6LcleWTJeo:eqD1vMxmWKQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=a6LcleWTJeo:eqD1vMxmWKQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=a6LcleWTJeo:eqD1vMxmWKQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=a6LcleWTJeo:eqD1vMxmWKQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=a6LcleWTJeo:eqD1vMxmWKQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/a6LcleWTJeo" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2012/2/5/people-dont-think-in-tables.html</feedburner:origLink></entry><entry><title>New Videos on CQRS/DDD and Practical CQRS</title><category term="Azure" /><category term="CQRS" /><category term="Cloud Computing" /><category term="DDD" /><category term="Event Sourcing" /><category term="Lokad" /><id>http://abdullin.com/journal/2012/1/20/new-videos-on-cqrsddd-and-practical-cqrs.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/erBE6YufLK8/new-videos-on-cqrsddd-and-practical-cqrs.html" /><author><name>Rinat Abdullin</name></author><published>2012-01-20T13:04:53Z</published><updated>2012-01-20T13:04:53Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Thanks to awesome guys from &lt;a href="http://www.dotnet-austria.at/"&gt;Austrian Alt.NET&lt;/a&gt; (and particularly  &lt;a href="https://twitter.com/#!/JoergEg"&gt;Jörg Egretzberger&lt;/a&gt;) there has been an opportunity for me to speak with Greg Young at Professional.NET in Vienna on September 2011. And here are the videos that were made there.&lt;/p&gt;

&lt;p&gt;It's recommended to watch them in the provided order: first Greg's "CQRS and DDD" and then my "Practical CQRS"&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Please, keep in mind, that this event took place more than 4 months from now; it also was the first talk I've done together with Greg (meaning that I became slightly less stupid and naive since then, especially during the &lt;a href="http://abdullin.com/roadtrip-2011"&gt;CQRS RoadTrip 2011&lt;/a&gt;; at least that's what I hope). &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;CQRS and Domain Driven Design&lt;/h2&gt;

&lt;p&gt;by Greg Young. Direct link: &lt;a href="http://youtu.be/KXqrBySgX-s"&gt;http://youtu.be/KXqrBySgX-s&lt;/a&gt;&lt;/p&gt;

&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/KXqrBySgX-s" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;h2&gt;Practical CQRS in Cloud&lt;/h2&gt;

&lt;p&gt;by Rinat Abdullin. Direct Link: &lt;a href="http://youtu.be/CnvO_nlvrps"&gt;http://youtu.be/CnvO_nlvrps&lt;/a&gt; | &lt;a href="http://abdullin.com/storage/publish/2011-09-15_Vienna.pdf"&gt;PDF&lt;/a&gt;&lt;/p&gt;

&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/CnvO_nlvrps" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;I hope you enjoy them. Once again, kudos to terrific guys from &lt;a href="http://www.dotnet-austria.at/"&gt;Austrian Alt.NET&lt;/a&gt; community for making these recordings possible.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=erBE6YufLK8:47YNBtAT5ok:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=erBE6YufLK8:47YNBtAT5ok:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=erBE6YufLK8:47YNBtAT5ok:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=erBE6YufLK8:47YNBtAT5ok:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=erBE6YufLK8:47YNBtAT5ok:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=erBE6YufLK8:47YNBtAT5ok:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=erBE6YufLK8:47YNBtAT5ok:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/erBE6YufLK8" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2012/1/20/new-videos-on-cqrsddd-and-practical-cqrs.html</feedburner:origLink></entry><entry><title>Run Lokad.CQRS code natively on Windows Azure</title><category term="Azure" /><category term="C#" /><category term="CQRS" /><category term="Cloud Computing" /><category term="Event Sourcing" /><category term="Lokad" /><category term="xLim" /><id>http://abdullin.com/journal/2012/1/14/run-lokadcqrs-code-natively-on-windows-azure.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/H4MM_GC8_TA/run-lokadcqrs-code-natively-on-windows-azure.html" /><author><name>Rinat Abdullin</name></author><published>2012-01-14T14:09:08Z</published><updated>2012-01-14T14:09:08Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;As it seems, the most common use of &lt;a href="https://github.com/lokad/lokad-cqrs/"&gt;Lokad.CQRS Sample&lt;/a&gt; these days is for building CQRS-based applications for Intranet (and migrating legacy projects). I didn't see that coming, but glad that the latest "lean" version makes some sense to people (&lt;a href="http://abdullin.com/journal/2012/1/5/announcing-lokadcqrs-vlean-sampleproject-and-tools.html"&gt;more about it&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;However, one of the initial purposes of this Sample is to &lt;strong&gt;enable and demonstrate cross-cloud portability&lt;/strong&gt; of projects developed using abstractions from &lt;code&gt;Lokad.Cqrs.Portable&lt;/code&gt;. That's how we use it at &lt;a href="http://www.lokad.com/forecasting-technology.ashx"&gt;Lokad&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So to highlight this (and to help folks from &lt;em&gt;Microsoft CQRS Advisory Board&lt;/em&gt; that showed interest in trying Lokad.CQRS with Azure), I've added two new projects: &lt;code&gt;Sample.Azure.Wires&lt;/code&gt; and &lt;code&gt;Sample.Azure.Deploy&lt;/code&gt;. There is nothing really special, first project just wires SampleProject to run on Windows Azure in a Worker Role, without touching existing domain code. Second project is the actual deployment. &lt;/p&gt;

&lt;p&gt;As expected, trace output is similar to the one we get from running sample in on-premises mode (via  &lt;code&gt;Sample.Engine&lt;/code&gt; console).&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/01/2012-01-14_cqrs-in-azure.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Obviously, this worker is wired to use native components of Windows Azure, instead of file system. These components (developed in Lokad and production-tested over the last few years in various scenarios) include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BlockBlobTapeStorage (used for append-only event streams on Azure)&lt;/li&gt;
&lt;li&gt;AzureAtomicStorage (used for storing documents, saga state and persistent read models)&lt;/li&gt;
&lt;li&gt;BlobStreamingStorage (used for streaming large BLOBs for Big DataProcessing)&lt;/li&gt;
&lt;li&gt;Azure Queues (for your message sending needs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have latest Azure SDK installed, just open &lt;code&gt;Lokad.CQRS.Sample.withAzure.sln&lt;/code&gt; to see these additional Azure projects and get a taste of &lt;a href="http://bliki.abdullin.com/event-sourcing/why"&gt;event sourcing&lt;/a&gt; on the cloud (actually tastes exactly like any other ES, but feels cooler).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintenance Tip:&lt;/strong&gt; By the way, you can download domain log file (&lt;code&gt;sample-tapes/domain.tmd&lt;/code&gt;) from the Azure Storage to your disk and open it with Audit tool. This &lt;strong&gt;helps to visualize and investigate processes that happen in your CQRS system on the cloud&lt;/strong&gt; (actually saved my day more than once, when production systems hit unexpected problems). Likewise you can also download and investigate event streams of any single aggregate. &lt;/p&gt;

&lt;p&gt;Actually, this Audit tool was also designed to open event streams directly from Azure (and allow sending selected messages back or rebuilding all projections), however this functionality is not ported to open source yet. If somebody finds it useful, I'll try to find time and export it (there is nothing really fancy there, though - just using append-only nature of event streams for efficient data replication from remote cloud to local machine).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintenance Tip:&lt;/strong&gt; Those, that plan to use this in a production, might want to plug the quarantine into the message handlers. For instance, &lt;a href="https://gist.github.com/1027419"&gt;here is a sample&lt;/a&gt; that records every handler failure and send a detailed report (with stack traces and message information) to email as soon as message is quarantined. The latter helps to deal with cloud problems really fast.&lt;/p&gt;

&lt;p&gt;The next thing I want to include in this Sample Project is a lean Web UI, using ASP.NET MVC 3 Razor Views with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and &lt;a href="http://twitter.github.com/bootstrap/"&gt;Bootstrap.css&lt;/a&gt;. Just to demonstrate how easy it is to add browser-friendly and fast Web UI to existing CQRS systems (and have it hosted on-premises or in the cloud, of course). What do you think?&lt;/p&gt;

&lt;p&gt;Meanwhile, have fun, join the &lt;a href="https://groups.google.com/forum/#!forum/lokad"&gt;community&lt;/a&gt; of people &lt;a href="https://groups.google.com/forum/#!topic/lokad/kD53JYzkV0o"&gt;abusing the project&lt;/a&gt; and be sure to fill in &lt;a href="http://t.co/3zBMC52n"&gt;CQRS Survey put out by P&amp;amp;P Team&lt;/a&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=H4MM_GC8_TA:lwrMQdJemjc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=H4MM_GC8_TA:lwrMQdJemjc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=H4MM_GC8_TA:lwrMQdJemjc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=H4MM_GC8_TA:lwrMQdJemjc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=H4MM_GC8_TA:lwrMQdJemjc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=H4MM_GC8_TA:lwrMQdJemjc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=H4MM_GC8_TA:lwrMQdJemjc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/H4MM_GC8_TA" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2012/1/14/run-lokadcqrs-code-natively-on-windows-azure.html</feedburner:origLink></entry><entry><title>Announcing Lokad.CQRS vLean - SampleProject and Tools</title><category term="Azure" /><category term="C#" /><category term="CQRS" /><category term="Cloud Computing" /><category term="DDD" /><category term="Event Sourcing" /><category term="Lokad" /><category term="xLim" /><id>http://abdullin.com/journal/2012/1/5/announcing-lokadcqrs-vlean-sampleproject-and-tools.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/D85sGsdQ_ks/announcing-lokadcqrs-vlean-sampleproject-and-tools.html" /><author><name>Rinat Abdullin</name></author><published>2012-01-05T17:49:25Z</published><updated>2012-01-05T17:49:25Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;I've just finished assembling pre-release of Lokad.CQRS vLean (&lt;a href="https://github.com/Lokad/lokad-cqrs/tree/lean"&gt;lean branch in github repository&lt;/a&gt;). From of this version &lt;strong&gt;Lokad.CQRS is no longer a framework&lt;/strong&gt;, it is a &lt;strong&gt;full sample&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;As such, Lokad.CQRS could be used for &lt;strong&gt;learning about event centric development&lt;/strong&gt; (&lt;a href="http://abdullin.com/cqrs/"&gt;CQRS/DDD&lt;/a&gt; with event sourcing and ability to deploy in cloud and on-premises). Gradually growing series of articles in &lt;a href="http://bliki.abdullin.com/"&gt;my bliki&lt;/a&gt; could provide some theoretical background.&lt;/p&gt;

&lt;p&gt;You can also use Lokad.CQRS to jumpstart new projects by copying the entire &lt;code&gt;SampleProject&lt;/code&gt; to your system and then modifying it to your needs. That's essentially how we start new projects at &lt;a href="http://www.lokad.com/"&gt;Lokad&lt;/a&gt; these days.&lt;/p&gt;

&lt;p&gt;Because of this transition from "Framework" to "Sample with Sources" (aka "Reference Implementation"), I was finally able to include a lot of new material into this branch.&lt;/p&gt;

&lt;h2&gt;Sample Project&lt;/h2&gt;

&lt;p&gt;I've ripped part of domain code (simple account+users setup) from one of our projects, along with all the accompanying tooling, tests and engine. Current approach to event sourcing is also included (as explained in the &lt;a href="http://bliki.abdullin.com/"&gt;bliki&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The project currently &lt;strong&gt;does not include&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Deployment runners for Azure.Cloud&lt;/strong&gt; (planned later, however Lokad.CQRS users should have pretty good sense of reconfiguring the domain to run in Azure).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web UI&lt;/strong&gt; (but I might add it later, if time permits, since Razor + Bootstrap make really pleasant and fast development with this architecture).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll try to add these later (community contributions are also awesome).&lt;/p&gt;

&lt;p&gt;Absence of Web UI makes it harder to visualize what's going inside. However you can still run tests and also start &lt;code&gt;Sample.Engine&lt;/code&gt; (configured with file-based persistence and queues), that will fire a few commands, which will produce events that will be wired to sagas and projections. Just like in the real world.&lt;/p&gt;

&lt;p&gt;Plus, this project includes some sample code and tools that are wired to it. These are used exactly how we currently use them (although not necessary how we will use them a few months later). Read below for more info.&lt;/p&gt;

&lt;h2&gt;Contracts DSL&lt;/h2&gt;

&lt;p&gt;Lokad Contracts DSL is an optional console utility that you can run in the background. It tracks changes to files with special compact syntax (as mentioned in &lt;a href="http://bliki.abdullin.com/event-centric/commands-events"&gt;commands and events&lt;/a&gt; on bliki) and updates CS file. Changes are immediate upon saving file (and ReSharper immediately picks them). This is an improved version of &lt;a href="https://github.com/Lokad/lokad-codedsl"&gt;Lokad Code DSL&lt;/a&gt;, it supports identities and can auto-generate interfaces for aggregates and aggregate state classes.&lt;/p&gt;

&lt;p&gt;You can try this out by starting &lt;code&gt;SampleProject\Tools\Dsl&lt;/code&gt; project and then doing some changes to &lt;code&gt;SampleProject\Domain\Sample.Contracts\Messages.tt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Current DSL code generates contracts classes that are compatible with &lt;code&gt;DataContracts&lt;/code&gt;, &lt;code&gt;ServiceStack.JSON&lt;/code&gt; and &lt;code&gt;ProtoBuf&lt;/code&gt;. Here are how they look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[DataContract(Namespace = "Sample")]
public partial class AddSecurityPassword : ICommand&amp;lt;SecurityId&amp;gt;
{
    [DataMember(Order = 1)] public SecurityId Id { get; private set; }
    [DataMember(Order = 2)] public string DisplayName { get; private set; }
    [DataMember(Order = 3)] public string Login { get; private set; }
    [DataMember(Order = 4)] public string Password { get; private set; }

    AddSecurityPassword () {}
    public AddSecurityPassword (SecurityId id, string displayName, string login, string password)
    {
        Id = id;
        DisplayName = displayName;
        Login = login;
        Password = password;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Audit Tool&lt;/h2&gt;

&lt;p&gt;After you have run &lt;code&gt;Sample.Engine&lt;/code&gt;, try starting &lt;code&gt;Audit&lt;/code&gt; and opening  with it this file &lt;code&gt;temp\sample-tapes\domain.tmd&lt;/code&gt; (located in folder where the engine run). You should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/01/2012-01-05_lokad-audit.png?__SQUARESPACE_CACHEVERSION=1325783136000" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;You'll probably figure out the purpose of color coding (or you could look out in the sources). &lt;/p&gt;

&lt;p&gt;BTW, here's how the other tab looks like - it is used for automatically detecting and wiring all &lt;a href="http://bliki.abdullin.com/event-sourcing/projections"&gt;projections&lt;/a&gt; and then running the selected event stream through them:&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/01/2012-01-05_rebuild-views.png?__SQUARESPACE_CACHEVERSION=1325783286674" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Please keep in mind, that this is a fast rip from internal code, so a few buttons and functionality might not make full sense in the file-based context (i.e. domain log synchronization).&lt;/p&gt;

&lt;h2&gt;Simple Testing&lt;/h2&gt;

&lt;p&gt;I've been mentioning heavy abuse of Greg's SimpleTesting for dealing with &lt;a href="http://bliki.abdullin.com/event-sourcing/specifications"&gt;specifications&lt;/a&gt; to test &lt;a href="http://bliki.abdullin.com/event-sourcing/aggregates"&gt;Aggregates&lt;/a&gt;. Source code for that is included (and for printing out them in readable format). Just fire your NUnit (either directly or via ReSharper):&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2012/01/2012-01-05_simple-testing.png?__SQUARESPACE_CACHEVERSION=1325783505835" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This setup currently supports usual AR+ES testing, plus testing exceptions thrown by the domain code (domain errors), plus dealing with services and time.&lt;/p&gt;

&lt;h2&gt;Core Changes&lt;/h2&gt;

&lt;p&gt;There were a few core changes in the actual Lokad.CQRS framework. They were caused by the need to move forward and support wider range of scenarios (and better scalability). Actually, these features were mostly related to throwing things out - all builder syntax and containers. In the current version you wire everything without using overcomplicated builders. This leads to fewer dependencies and simpler code.&lt;/p&gt;

&lt;p&gt;If you don't know, how old builder code translates to the new one - just check &lt;code&gt;Wires&lt;/code&gt; and &lt;code&gt;Engine&lt;/code&gt; projects in &lt;code&gt;SampleProject&lt;/code&gt; (in addition to &lt;code&gt;Snippets&lt;/code&gt; and unit tests for core building blocks).&lt;/p&gt;

&lt;p&gt;In the spirit, we are gradually drifting away from style of architectures that is similar to NServiceBus, MassTransit and RhinoQueues (where you have handler classes plugged into the container for you). Instead, we are going directly for the type of architectures described by the outstanding &lt;a href="http://zguide.zeromq.org/page:all"&gt;ZMQ guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What's Next&lt;/h2&gt;

&lt;p&gt;As always, your feedback is always welcome (it helped to shape the current release and let us move forward). Please share it (along with any questions you might have) in &lt;a href="https://groups.google.com/forum/#!forum/lokad"&gt;Lokad community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot more is planned in this world along the following directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplifying the core even further, along with solidifying the backing theory, based on real-world experience.&lt;/li&gt;
&lt;li&gt;Better support of multiple clouds (just Azure is not enough)&lt;/li&gt;
&lt;li&gt;Realt-time performance scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned and participate in the community, if you are interested!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=D85sGsdQ_ks:UmgDOgAwaVM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=D85sGsdQ_ks:UmgDOgAwaVM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=D85sGsdQ_ks:UmgDOgAwaVM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=D85sGsdQ_ks:UmgDOgAwaVM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=D85sGsdQ_ks:UmgDOgAwaVM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=D85sGsdQ_ks:UmgDOgAwaVM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=D85sGsdQ_ks:UmgDOgAwaVM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/D85sGsdQ_ks" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2012/1/5/announcing-lokadcqrs-vlean-sampleproject-and-tools.html</feedburner:origLink></entry><entry><title>Roadtrip-2011 Lessons Learned at #eventcentric in Kiev</title><category term="CQRS" /><category term="DDD" /><category term="Lokad" /><id>http://abdullin.com/journal/2011/10/24/roadtrip-2011-lessons-learned-at-eventcentric-in-kiev.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/uqdFiz-B39g/roadtrip-2011-lessons-learned-at-eventcentric-in-kiev.html" /><author><name>Rinat Abdullin</name></author><published>2011-10-24T17:46:40Z</published><updated>2011-10-24T17:46:40Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;In short - this spontaneous &lt;strong&gt;Event centric weekend in Kiev was totally awesome and rewarding&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Check out &lt;a href="http://twitter.com/#!/search/eventcentric"&gt;tweets&lt;/a&gt;, if you are interested in what others feel (people are talking about sparkles in the eyes and #eventcentric cult :)&lt;/p&gt;

&lt;p&gt;This event was organized as a part of &lt;a href="http://abdullin.com/roadtrip-2011"&gt;Road-Trip 2011&lt;/a&gt; with Greg Young. There were quite a few other adventures that happened along the way earlier - too much to write about. So I'll just focus on the last weekend and lessons learned.&lt;/p&gt;

&lt;p&gt;Event Centric weekend in Kiev was a two day class held for free in Kiev. Greg Young was doing his well-known CQRS/DDD course, I've got to share some of my practical experience with such systems "in the wild" (including various cloud options). &lt;/p&gt;

&lt;p&gt;Room was packed with 90+ people from multiple Ukrainian cities and also from a few cities in Russia. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.luxoft.ru/about/delivery/ukraine.html"&gt;Luxoft Ukraine&lt;/a&gt; helped us immensely by providing with the place to do that. Irina Odina of Luxoft deserves a medal (or two raises in salary) for staying with us through the weekends and helping with the coffee breaks. &lt;em&gt;Mike Chaliy&lt;/em&gt; and really friendly Kiev &lt;a href="http://kievalt.net/"&gt;Alt.NET community&lt;/a&gt; were helping with afterparties, logistics and coping with unexpected.&lt;/p&gt;

&lt;p&gt;Here's what I've learned during this event:&lt;/p&gt;

&lt;p&gt;One of the best ways to &lt;strong&gt;strengthen your understanding in a field&lt;/strong&gt; is to &lt;strong&gt;speak and share&lt;/strong&gt;. For instance, I've learned a lot simply by explaining aggregates and sagas to the audience and then seeing that not everybody gets a clear and coherent picture. Or, when you get an question from an audience, and you know an answer to that question, but can't explain this immediately in clear and concise language immediately. Then Greg comes in with his explanation and reveals missing pieces and steps in my own explanation and understanding.&lt;/p&gt;

&lt;p&gt;Showing my own hacks to the theory and practice (and sharing how everything works really nicely in distributed teams and cloud environments) is always a pleasure of its own.&lt;/p&gt;

&lt;p&gt;There were a few smaller realizations of its own along the way. The most important one of them was about more clear and focused picture of bringing multiple complex systems together in a way to limit complexity and facilitate development (obviously, with limited time and resources). Basically that's the a-ha understanding of how to separate elements of a distributed systems (bounded contexts, sagas, services, cloud scalability points), while keeping each element highly specialized (and relatively simple).&lt;/p&gt;

&lt;p&gt;In essence, this is a direct analogy with human body, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bounded contexts (matching aggregate roots in extreme) == &lt;a href="http://en.wikipedia.org/wiki/Neuron"&gt;neurons&lt;/a&gt; that are completely isolated from each other, but can exhibit complex behaviors and have a short-term memory;&lt;/li&gt;
&lt;li&gt;Sagas (stateful or stateless) == &lt;a href="http://en.wikipedia.org/wiki/Neuroglia"&gt;glial cells&lt;/a&gt; that protect and insulate neurons from each other, while connecting them;&lt;/li&gt;
&lt;li&gt;Stateless services (integration, number crunching, file processing etc) == specialized &lt;a href="http://en.wikipedia.org/wiki/Organ_(anatomy"&gt;organs&lt;/a&gt;) in a body that can get some job done, but tend not to have any memory on their own. They react to impulses and send back information about the events that happened to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This analogy (coupled with the basic principles of biology) actually explained me better how to build and evolve really interesting IT systems, while keeping core cells simple. In short - that's just like how evolution does this. That was a really important realization since before that I simply could not understand how to bring together behavioristic CQRS-driven systems with elastically scalable functional elements of big data crunching or messy technology-dependent integrations. This understanding comes just in the right time - as we are starting yet another project at Lokad these days. I'll definitely blog about that more of that later.&lt;/p&gt;

&lt;p&gt;A few smaller realizations were coupled to Sagas (explaining them better, to be precise) and transition from domain models to Aggregate Roots with Event Sourcing via TryDo-Do logic (nothing essential to the production but still helps to see and explain better)&lt;/p&gt;

&lt;p&gt;By the way, the road-trip is not other yet. There is still a lot to learn and do. &lt;/p&gt;

&lt;p&gt;So far, thanks to everybody for helping to learn and have some wonderful time!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=uqdFiz-B39g:0JrU-FyfCLs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=uqdFiz-B39g:0JrU-FyfCLs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=uqdFiz-B39g:0JrU-FyfCLs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=uqdFiz-B39g:0JrU-FyfCLs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=uqdFiz-B39g:0JrU-FyfCLs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=uqdFiz-B39g:0JrU-FyfCLs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=uqdFiz-B39g:0JrU-FyfCLs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/uqdFiz-B39g" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/10/24/roadtrip-2011-lessons-learned-at-eventcentric-in-kiev.html</feedburner:origLink></entry><entry><title>Experience with CQRS+ES/DDD in Current Project</title><category term="Azure" /><category term="C#" /><category term="CQRS" /><category term="Cloud Computing" /><category term="DDD" /><category term="DSL" /><category term="Event Sourcing" /><category term="Lokad" /><category term="autofac" /><category term="xLim" /><id>http://abdullin.com/journal/2011/10/12/experience-with-cqrsesddd-in-current-project.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/VAyW5uQ37zE/experience-with-cqrsesddd-in-current-project.html" /><author><name>Rinat Abdullin</name></author><published>2011-10-11T19:55:51Z</published><updated>2011-10-11T19:55:51Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Just a quick summary of tech I'm using in the current project. So far it works out rather nicely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project targets Windows Azure&lt;/strong&gt;. However, just like our other recent projects at Lokad, it is developed to be cloud-ignorant (can be deployed anywhere where Microsoft .NET can be run).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development machine&lt;/strong&gt;: MacBook Air 2011 13' with intel i5 CPU (1.7Mhz), 4GB RAM and 128 GB SSD. OSX (Lion) with Windows 7 running in Parallels. I used to boot it in BootCamp (for native performance) a few times and then switched to pure VM mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development IDE&lt;/strong&gt;: Visual Studio 2010 with ReSharper 6 (solution-wide analysis is OFF). Windows Azure SDK is installed (with Emulator and Storage) However it's not used at this project at all, due to being rather inefficient with resources of my MBA. File system is used for both queues and storage instead. In production  they will be reconfigured to use Azure-specific adapters (abstractions provided by Lokad.Cqrs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;: Distributed system with "CQRS approach" where aggregates are implemented using &lt;a href="http://bliki.abdullin.com/event-sourcing/why"&gt;Event Sourcing&lt;/a&gt;. Business processes are stateless routing rules (as opposed to more classical sagas), with more complex workflow logic and state being pushed to aggregates or dedicated entities. The latter makes perfect sense with event sourcing and deployments in cloud environments. &lt;/p&gt;

&lt;p&gt;Read-models are implemented using document model for now (each view is a single document being updated atomically). Still no SQL. Huge lists will be handled on per-platform basis (if they ever become a problem worth solving).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frameworks&lt;/strong&gt;: Domain logic (the most complex part) does not really depend on anything except Base Class library (System. namespace). Infrastructure (essentially, configuration code) relies on ProtoBuf/ServiceStack for serialization and Lokad.CQRS with Autofac for hosting everything server-side. Web UI - ASP.NET.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;: NUnit used to wire custom specifications (code copied and adjusted from SimpleTesting).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom tools&lt;/strong&gt;: using side helper to generate command/event contract classes (got lots of them) out of compact DSL. C# code is generated whenever I do Ctrl-S and is immediately picked up by R# (this is slightly improved version if T4-driven CodeDSL. Improvement - it no longer depends on T4 and hence is much easier to change. Actual DSL generation is completely within the project now. &lt;a href="https://gist.github.com/1268198"&gt;details are in gist&lt;/a&gt;. This custom tool can be dropped at any point (completely along with the DSL files), contract files will stay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes development complex&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it's hard to get domain models and bounded contexts right (however coding or testing itself is no longer an issue. Scalability and performance - even more so);&lt;/li&gt;
&lt;li&gt;hard to communicate finer-grain detail to people used to SQL/ORM;&lt;/li&gt;
&lt;li&gt;I still haven't figured how to explain (graph) business processes. So far sequence diagrams work the best;&lt;/li&gt;
&lt;li&gt;Event sourcing plumbing had to be implemented manually (EventStore was too much of a dependency, something more simple was needed).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the record, this project is a replacement of the project that was using following stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NHibernate + FluentNHibernate&lt;/li&gt;
&lt;li&gt;Newtonsoft JSON&lt;/li&gt;
&lt;li&gt;Autofac&lt;/li&gt;
&lt;li&gt;Windows Azure&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;li&gt;Protobuf&lt;/li&gt;
&lt;li&gt;Lokad Shared Libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Migrating existing system to ES requires an additional custom "Reverse Engineering" app, which scans database and generates events for the new deployment (roughly 300000 events). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best lessons learned&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NHibernate and ORMs in general are a pain (especially in systems that has to live through more than 1 deployment). Although we are so used to that pain, that it does not feel. Well, until you have to go back and work on projects that have not been migrated, yet.&lt;/li&gt;
&lt;li&gt;Specification tests (and ability to use them as a living documentation readable by non-dev people) create some interesting additional opportunities.&lt;/li&gt;
&lt;li&gt;Simpler the code is - better.&lt;/li&gt;
&lt;li&gt;Abstraction from the persistence not only reduces friction, but also allows to have multiple deployment options (in cloud, on-premises, in memory etc).&lt;/li&gt;
&lt;li&gt;If domain model is defined (i.e.: there is BC and specifications for an aggregate), then actually coding Aggregate root with event sourcing (AR+ES) feels like a monkey coding - you just need to make all tests pass.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/wiki/pat-helland.html"&gt;Helland's principles&lt;/a&gt; (of building distributed systems in eventually consistent world) can be enforced in CQRS/DDD world, if we get rid of sagas in classical interpretation (something that has state, subscribes to events and publishes commands), replacing them with stateless routing rules and pushing state to entities (aggregates). Underlying framework becomes much easier (no need to explicitly manage and correlate saga state). Dynamic scalability - too.&lt;/li&gt;
&lt;li&gt;I'm using Event Sourcing even for simple things (like replicated user logins), simply because introducing Sql (or any other storage) would add too much complexity and friction without any visible gains.&lt;/li&gt;
&lt;li&gt;Using specifications for testing AR+ES has another side advantage - I added a single unit test, that gathers pre-populated commands and events from these specifications. This data is round-ripped through a few serializers and compared. This ensures that message contracts (and their use) stays compatible with all primary serialization options (ProtoBuf, JSON). Helps to catch use of DateTimeKind issues (which is  generally not supported by JSON+PB).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obviously, this is highly subjective experience (and really rewarding). It  might change as we are pushing the project to the first release (and further). Your mileage may vary. &lt;strong&gt;If you are really interested in long-term production experience - please ask me about that in a few years&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;PS: This is not the first project where ES has been used. But it combines the best lessons learned in lean development at &lt;a href="http://www.lokad.com/aboutus.ashx"&gt;Lokad&lt;/a&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=VAyW5uQ37zE:xs8eOUzL5Os:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=VAyW5uQ37zE:xs8eOUzL5Os:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=VAyW5uQ37zE:xs8eOUzL5Os:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=VAyW5uQ37zE:xs8eOUzL5Os:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=VAyW5uQ37zE:xs8eOUzL5Os:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=VAyW5uQ37zE:xs8eOUzL5Os:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=VAyW5uQ37zE:xs8eOUzL5Os:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/VAyW5uQ37zE" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/10/12/experience-with-cqrsesddd-in-current-project.html</feedburner:origLink></entry><entry><title>Golden Rule of Technology</title><category term="Lokad" /><category term="management" /><id>http://abdullin.com/journal/2011/9/28/golden-rule-of-technology.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/CWGCSv9evlk/golden-rule-of-technology.html" /><author><name>Rinat Abdullin</name></author><published>2011-09-28T11:54:37Z</published><updated>2011-09-28T11:54:37Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;The rule says: &lt;strong&gt;1 new technology goes into codebase only after 1 old technology goes out&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is a &lt;em&gt;simple empirical rule&lt;/em&gt; that we've coined with &lt;a href="http://vermorel.com/"&gt;Joannes&lt;/a&gt;, while talking about business and managing technology. As it turns out, this rule makes a really nice guideline for planning future development.&lt;/p&gt;

&lt;p&gt;The rule can apply to all sorts of things: new technological concepts, frameworks, ideas, tools and software. Basically, a &lt;strong&gt;technology&lt;/strong&gt; in this list is &lt;em&gt;anything that a new Junior Developer will have to learn about the project, before he can productively work the assignments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This approach encourages &lt;em&gt;technology pruning&lt;/em&gt; and explains how to structure technological evolution of your company, almost turning this process into a game. This is quite important, since otherwise it will be hard to "embrace the change" and leverage new technologies and tools, as opposed to being hit hard by every new "revolution". Essentially it helps to define your own &lt;a href="http://www.thoughtworks.com/radar"&gt;Technology Radar&lt;/a&gt; at the project level.&lt;/p&gt;

&lt;p&gt;For instance, we have the following evolution path for the User Interfaces in the world of Microsoft .NET Framework: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows.Forms&lt;/li&gt;
&lt;li&gt;Silverlight/WPF&lt;/li&gt;
&lt;li&gt;Windows 8/HTML5/some Metro UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you treat these UI technologies as something to focus completely on, then every new change might be quite expensive (i.e. from Silverlight to HTML5), because of the way the problem is being structured:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We are going to develop new eCommerce suite with Silverlight. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, treating technologies as something transient and replaceable can reduce costs and even improve architecture (making it more resilient to risks and changes). Consider this way to structure a problem:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;We are going to deliver eCommerce suite, while using Silverlight for UI for the time being.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obviously, this approach requires an architecture that favors decoupling and simplicity (i.e.: &lt;a href="http://abdullin.com/cqrs/"&gt;CQRS/DDD/ES methodology&lt;/a&gt;). However, this is not limited by the software architecture alone. Here are some samples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frameworks&lt;/li&gt;
&lt;li&gt;Version Control Systems&lt;/li&gt;
&lt;li&gt;Testing Approaches&lt;/li&gt;
&lt;li&gt;Project Management Concepts&lt;/li&gt;
&lt;li&gt;Integration Servers&lt;/li&gt;
&lt;li&gt;Deployment Strategies&lt;/li&gt;
&lt;li&gt;Serialization Formats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another interesting side effect of this Golder Rule of Technology is that it &lt;strong&gt;encourages developers to simplify and refactor&lt;/strong&gt; in order to be able to try some new cool things in the project.&lt;/p&gt;

&lt;p&gt;And sometimes, when you get rid of an old technology, there already is so much improvement, that you don't even want to add anything instead. One example of such replacement in place is gradual migration from traditional SQL-driven persistence to &lt;a href="http://abdullin.com/journal/2011/9/27/why-event-sourcing.html"&gt;Event Sourcing&lt;/a&gt; at &lt;a href="http://www.lokad.com/aboutus.ashx"&gt;our place&lt;/a&gt;. It allows us to discard quite a few items from the current stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NHibernate with all the related binary dependencies &lt;/li&gt;
&lt;li&gt;SQL Servers along with the entire concept of relational database and &lt;a href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch"&gt;object-relational impedance mismatch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Evolutionary databases and managing them (including upgrade scripts and unit tests working against mock databases to verify behaviors on continuous integration servers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another practical sample would be - planned replacement of API implemented as REST via WCF (with SOAP and all sorts of weird configuration problems) towards a dead-simple implementation on HttpListener.&lt;/p&gt;

&lt;p&gt;An interesting thing is that I never really considered complexity of technologies related to a feature till starting to think about that in terms of "Return on Technology Introduced". As it turns out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usage of technologies is extremely overrated (sometimes attributed to the marketing hype related to certain buzz-words).&lt;/li&gt;
&lt;li&gt;Usage of additional technologies tends to increase both burden and complexity of a project at hand. Emprical evidence suggests that linear increases in these - lead to exponential rise in project costs. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The process of complexity increase can continue till the project becomes so expensive that it stalls. By reducing the number of non-essential technologies used, we can have better management of overall complexity (fighting delays, quality problems and costs).&lt;/p&gt;

&lt;p&gt;In essence, &lt;strong&gt;simplicity is a technology of its own&lt;/strong&gt;. But it does not count as one.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=CWGCSv9evlk:bQNVw4I_gSY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=CWGCSv9evlk:bQNVw4I_gSY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=CWGCSv9evlk:bQNVw4I_gSY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=CWGCSv9evlk:bQNVw4I_gSY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=CWGCSv9evlk:bQNVw4I_gSY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=CWGCSv9evlk:bQNVw4I_gSY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=CWGCSv9evlk:bQNVw4I_gSY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/CWGCSv9evlk" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/9/28/golden-rule-of-technology.html</feedburner:origLink></entry><entry><title>.NET Sample of Marrying CQRS, JS, and Http</title><category term="Azure" /><category term="C#" /><category term="CQRS" /><category term="Cloud Computing" /><category term="Lokad" /><category term="xLim" /><id>http://abdullin.com/journal/2011/9/1/net-sample-of-marrying-cqrs-js-and-http.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/lBONtGYdZQ4/net-sample-of-marrying-cqrs-js-and-http.html" /><author><name>Rinat Abdullin</name></author><published>2011-09-01T16:53:18Z</published><updated>2011-09-01T16:53:18Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;We've just published a rather interesting .NET code sample illustrating interactions between a browser and a CQRS-like server with queue processing. The sample is implemented as a snippet on top of &lt;a href="http://lokad.github.com/lokad-cqrs/"&gt;Lokad.Cqrs&lt;/a&gt;, leveraging the latest codebase and new http endpoint functionality.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Just a reminder. Lokad.Cqrs is not a real framework. It is just a temp scaffolding that speeds up development of distributed systems following &lt;a href="http://abdullin.com/cqrs/"&gt;CQRS&lt;/a&gt; architecture principles. It enforces design that will make it easy to scale and move system between on-premises and cloud deployments (saving money, whenever possible). Core elements are made intentionally simple to educate and encourage eventually replacing them with solutions tailored specifically for the specific project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;HttpEndpoint is a new feature of Lokad.Cqrs, that demonstrates how easy it is to write some simple non-blocking web server and then put it to a good use. In the sample we do some interesting stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;host both CQRS engine and http server in the same process;&lt;/li&gt;
&lt;li&gt;actually start the entire process inside a unit test;&lt;/li&gt;
&lt;li&gt;serve some html, images and javascript to the web browser (tested with all major ones :)&lt;/li&gt;
&lt;li&gt;let browser post simplified commands to the memory queue on the server;&lt;/li&gt;
&lt;li&gt;process these commands in async, aggregating results to a simple view;&lt;/li&gt;
&lt;li&gt;use this view to display info back in the web browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sounds cool enough for a simple sample? Here's how it actually looks like:&lt;/p&gt;

&lt;p&gt;&lt;span class="full-image-block ssNonEditable"&gt;&lt;span&gt;&lt;img src="http://abdullin.com/storage/uploads/2011/09/2011-09-01_http-image.png?__SQUARESPACE_CACHEVERSION=1314894694835" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;You drag Lokad.CQRS logo around the canvas. Each mouse move generates an event, which is AJAX posted to HttpEndpoint, which adds a message to the queue. Another javascript queries a view for the stats like distance and average message throughput of this non-optimized code.&lt;/p&gt;

&lt;p&gt;Interested to see how simple this code is? It is shared with the community as open source within the Lokad.Cqrs/Snippets project in hope that it will be of any help. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check out &lt;a href="https://github.com/Lokad/lokad-cqrs/tree/next/Framework/Snippets/HttpEndpoint"&gt;ReadMe&lt;/a&gt; or just grab Lokad.CQRS (branch 'vnext') from github and run it locally.&lt;/li&gt;
&lt;li&gt;Ask questions in our &lt;a href="https://groups.google.com/forum/#!forum/lokad"&gt;community&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;BTW, the primary reasons, why HttpEndpoint functionality was added to Lokad.Cqrs were about supporting following simple scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;network message dispatch in non-Azure deployments of systems developed with Lokad.Cqrs;&lt;/li&gt;
&lt;li&gt;simple secure endpoints for posting commands and querying views (problem of long lists can be solved here);&lt;/li&gt;
&lt;li&gt;extremely simple built-in UI for certain maintenance scenarios in Lokad.Cqrs systems that should work nicely even with fast push deployments on Azure;&lt;/li&gt;
&lt;li&gt;an easy way to support XML/REST/JSON integration scenarios with 3rd party systems without the need to roll out ASMX/WCF/ASP.NET or whatever over-complicated mess.&lt;/li&gt;
&lt;li&gt;have all these endpoints (supporting multiple virtual urls on a single server) on the same machine with the server processes, saving money on small project deployments in the cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do you think of this sample?&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=lBONtGYdZQ4:bQlP1A_hwLE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=lBONtGYdZQ4:bQlP1A_hwLE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=lBONtGYdZQ4:bQlP1A_hwLE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=lBONtGYdZQ4:bQlP1A_hwLE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=lBONtGYdZQ4:bQlP1A_hwLE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=lBONtGYdZQ4:bQlP1A_hwLE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=lBONtGYdZQ4:bQlP1A_hwLE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/lBONtGYdZQ4" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/9/1/net-sample-of-marrying-cqrs-js-and-http.html</feedburner:origLink></entry><entry><title>Self-Improvement Process</title><category term="Lokad" /><category term="xLim" /><id>http://abdullin.com/journal/2011/7/17/self-improvement-process.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/vxy5tj5VtwE/self-improvement-process.html" /><author><name>Rinat Abdullin</name></author><published>2011-07-17T02:26:34Z</published><updated>2011-07-17T02:26:34Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Lately I've been doing a little bit of new and well-forgotten old things, while trying to become a better me. They also help me to reduce work pressure by offering something new for the brain to chew on.&lt;/p&gt;

&lt;p&gt;I just wanted to share these things (at least for the sake of writing down the links). We'll talk a little bit about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git;&lt;/li&gt;
&lt;li&gt;vim;&lt;/li&gt;
&lt;li&gt;LMAX and Martin Fowler;&lt;/li&gt;
&lt;li&gt;VerseQ;&lt;/li&gt;
&lt;li&gt;Lokad.CQRS and functional approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Git&lt;/h2&gt;

&lt;p&gt;I've started using git on a number of new learning projects. As I've mentioned it on a couple of occasions already, I start liking git more than mercurial, despite its steeper learning curve.&lt;/p&gt;

&lt;p&gt;By the way, Google Code has finally added git to their project support. Although they are way too much behind github both in usability and commits.&lt;/p&gt;

&lt;h2&gt;Vim&lt;/h2&gt;

&lt;p&gt;Subj, the good old editor coming from the terminal era. Exactly the one, where "the best way to generate a random string is to ask a student exit vim" (by the way, it is ":x" to exit with save-if-modified).&lt;/p&gt;

&lt;p&gt;I find using it more and more for common text editing tasks. That's where I'm writing articles and blog posts these days.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;And I'm getting really tempted to start replacing IDEs with vim in non-.NET environments. Developer's mind is better than any IDE anyway, especially when he or she deliberately keeps projects dead-simple.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, if you got interested in vim, then that's what your &lt;a href="http://symbolsystem.com/2010/12/15/this-is-your-brain-on-vim/"&gt;future will look like&lt;/a&gt;. If this didn't scare you, here's a &lt;a href="http://lucisferre.net/2011/07/15/vim-from-start-to-finish"&gt;quick intro&lt;/a&gt; from the eyes of guy from VS environment.&lt;/p&gt;

&lt;h2&gt;LMAX and Martin Fowler&lt;/h2&gt;

&lt;p&gt;It seems that all this CQRS/ES stuff is getting mainstream, since Martin Fowler wrote a bliki post on CQRS and really good overview of LMAX architecture: the latter is essentially an in-memory circular buffer that also acts as a queue for the event sourcing messages; processed by a single writer and multiple readers. All workers have access to each other location pointers and this avoid any locks altogether. Predefined buffer size and one-writer-only approach allows to achieve high hardware affinity (in other words, CPU likes it a lot).&lt;/p&gt;

&lt;p&gt;The study is highly &lt;a href="http://martinfowler.com/articles/lmax.html"&gt;recommended for a read&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;By the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bliki is term for versioned blog/wiki coined by Martin Fowler a while ago. These days people just use &lt;a href="http://pages.github.com/"&gt;github with markdown&lt;/a&gt; (for example, &lt;a href="http://lokad.github.com/cqrs/case-studies/2011-07-11-humanrecord"&gt;this Lokad.CQRS Study&lt;/a&gt; isn't a page, but just a markdown file in a github repository).&lt;/li&gt;
&lt;li&gt;Don't read Martin's pounding on branch-per-feature. I believe he got it wrong (and got quite a bit of pounding from the community afterwards).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;VerseQ&lt;/h2&gt;

&lt;p&gt;To keep up with the learning process, I've stepped back on improving my keyboard typing skills. I believe it would be a wise investment of my time to improve on something that is so tightly related to the job and thinking as the typing is. This (when coupled with vim) feels like reducing VS development friction by introducing ReSharper.&lt;/p&gt;

&lt;p&gt;For this task I'm currently sticking to &lt;a href="http://www.verseq.com/"&gt;VerseQ&lt;/a&gt;, which was recommended to me by &lt;em&gt;Vsevolod&lt;/em&gt;. VerseQ tutor simply keeps on generating pseudo-random strings for you to type. However these strings are not entirely random:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they include chords common to the language you practice (i.e.: "jg" is not common to English, while "li" is more common);&lt;/li&gt;
&lt;li&gt;next random string is based on the statistics captured so far. It will force you to practice your slowest keys and key combinations (or most erroneous ones).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recommended to give it a try, if you are typing more than 50 lines of text per day (emails or code alike).&lt;/p&gt;

&lt;h2&gt;Functional Stuff&lt;/h2&gt;

&lt;p&gt;In the previous post I've mentioned that it is possible to get a whooping number of messages per second on a single thread in &lt;a href="http://abdullin.com/journal/2011/7/17/lokadcqrs-getting-simpler-and-faster.html"&gt;Lokad.CQRS using lambda dispatchers&lt;/a&gt;. This comes from a simple realization that everything is either an aggregate/saga or a function. For example, handlers are just functions partially resolved from the container and executed against the message.&lt;/p&gt;

&lt;p&gt;Now, to be true with this kind of development you can easily achieve much higher throughput, if you switched to some other platform. I'm currently looking at akka for the small specific cases where extremely high performance would be needed (i.e.: message routing for Lokad.CQRS or doing some high-frequency data transfer). Fortunately enough, envelope and data formats of Lokad.CQRS are relatively cross-platform (protobuf to the rescue).&lt;/p&gt;

&lt;p&gt;With &lt;a href="http://akka.io/"&gt;akka&lt;/a&gt; you can get something like a &lt;a href="https://plus.google.com/u/0/112820434312193778084/posts/HdKFx4VQtJj"&gt;few millions of messages processed per second&lt;/a&gt;. The latter might be another life-saving option for devs and start-ups (constrained on resources) who are using Lokad.CQRS and are hitting some throughput limitations on elements of a decoupled/cloud system that are a bit hard/expensive to scale (load balancers and routers, for instance).&lt;/p&gt;

&lt;p&gt;Obviously I'm not planning to switch anything in Lokad.CQRS to akka and dead-simple functions editable in vim (no matter how tempting this might look, there always are real-world costs associated with such dreams). Yet, where possible to simplify things (i.e.: by throwing another framework out of the window) the experience and ideas will be reused in the approach. Especially, if they provide a clear and simple path of massively boosting performance of certain nodes in a decoupled app by switching them to the non.NET stacks.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;PS: if you post a comment and it does not show up within a day, please &lt;a href="http://abdullin.com/contact/"&gt;drop me a line&lt;/a&gt;. I get the feeling Squarespace has messed up it's spam protection badly again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=vxy5tj5VtwE:YdBd3mqkLVs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=vxy5tj5VtwE:YdBd3mqkLVs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=vxy5tj5VtwE:YdBd3mqkLVs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=vxy5tj5VtwE:YdBd3mqkLVs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=vxy5tj5VtwE:YdBd3mqkLVs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=vxy5tj5VtwE:YdBd3mqkLVs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=vxy5tj5VtwE:YdBd3mqkLVs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/vxy5tj5VtwE" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/7/17/self-improvement-process.html</feedburner:origLink></entry><entry><title>Lokad.CQRS - Getting Simpler and Faster</title><category term="Azure" /><category term="CQRS" /><category term="Lokad" /><id>http://abdullin.com/journal/2011/7/17/lokadcqrs-getting-simpler-and-faster.html</id><link rel="alternate" type="text/html" href="http://feeds.abdullin.com/~r/Shared-Libraries/~3/zlmTWYmYCEs/lokadcqrs-getting-simpler-and-faster.html" /><author><name>Rinat Abdullin</name></author><published>2011-07-16T18:27:32Z</published><updated>2011-07-16T18:27:32Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Recently I've been pushing a few changes into Lokad.CQRS trunk, as required by current Lokad projects. Two major ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy consumption of messages from completely separate projects;&lt;/li&gt;
&lt;li&gt;lambda dispatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Multi-verse consumption&lt;/h2&gt;

&lt;p&gt;The most important improvement is to &lt;strong&gt;simplify consumption of messages coming from different systems&lt;/strong&gt;. Consider situation, when project C consumes messages from projects A and B. Each project is in essence it's own universe with it's own dependencies and development speed. Message contracts are distributed in binary form of A.Contracts.dll, B.Contracts.dll etc.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;based on our experience at Lokad we strongly recommend to ensure that these contract libraries should depend only on System.* dlls. Otherwise managing multiple projects will become time-consuming task.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Problem was related to the fact, that given:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;project A defines its own base interface IMessageA for message classes;&lt;/li&gt;
&lt;li&gt;project B defines its own base interface IMessageB for message classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in the project C we can't define a consumer signature that will handle both base interfaces. &lt;/p&gt;

&lt;p&gt;As it turns out, the solution is quite simple. We can define polymorphic dispatcher to use &lt;em&gt;object&lt;/em&gt; as a base message class (could be done on the latest):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mdm.HandlerSample&amp;lt;IMyConsume&amp;lt;object&amp;gt;&amp;gt;(s =&amp;gt; s.Consume(null));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then actual handler could be defined as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class SomeHandler : IMyConsume&amp;lt;ProjectAMessage&amp;gt;, IMyConsume&amp;lt;ProjectBMessage&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This small refactoring actually allowed me to decouple polymorphic dispatcher from the actual dispatch process. The latter simplified things a lot and enabled dead-simple performance optimization.&lt;/p&gt;

&lt;p&gt;More than that, it allowed to move forward with our current projects within Lokad (where we have on average less than one developer per active project and thus can't waste any time on unnecessary friction).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is polymorphic dispatcher?&lt;/strong&gt; It is that complicated piece of code in Lokad.CQRS that allows you to define handlers as classes that inherit from various consuming interfaces (i.e.: IConsume[SpecificMessage] or IConsume[IMessageInterface]), while correctly resolving them through the IoC Container, handling scopes and transactions as needed.&lt;/p&gt;

&lt;h2&gt;Lambda Dispatch&lt;/h2&gt;

&lt;p&gt;Lokad.CQRS is rather simple (unless Azure slows it down) and hence it can be fast. Since we no longer have extremely tight coupling with the polymorphic complexity, we can dispatch directly to a delegate, which has form of lambda:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Action&amp;lt;ImmutableEnvelope&amp;gt; e =&amp;gt; /* do something */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is implemented as another dispatcher type available for all Lokad.CQRS partitions.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;c.Memory(m =&amp;gt;
    {
        m.AddMemorySender("test");
        m.AddMemoryProcess("test", x =&amp;gt; x.DispatcherIsLambda(Factory));
    }

static Action&amp;lt;ImmutableEnvelope&amp;gt; Factory(IComponentContext componentContext)
{
    var sender = componentContext.Resolve&amp;lt;IMessageSender&amp;gt;();
    return envelope =&amp;gt; sender.SendOne(envelope.Items[0].Content);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note, that we are actually using container once here, while building the lambda. Aside from that, there is neither reflection nor container resolution. This allows to get better performance. Below are some test results. First number goes for classical polymorphic dispatch, second one - for lambdas. MPS stands for messages per seconds.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;By the way, you can obviously &lt;strong&gt;combine different types of dispatchers&lt;/strong&gt; in a single Lokad.CQRS host.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Throughput performance test&lt;/strong&gt; (we fill queue with messages and then consume them as fast as possible in 1 thread, doing all proper ACK stuff):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Dev Store (don't laugh) - 11 / 11 mps&lt;/li&gt;
&lt;li&gt;Files - 1315 / 1350 mps&lt;/li&gt;
&lt;li&gt;Memory - 79000 / 101000 mps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the way, &lt;strong&gt;memory queues are equivalent of non-durable messaging&lt;/strong&gt;, while file queues are durable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reaction time test&lt;/strong&gt; (single thread sends message to itself, then pulls this message from the queue etc):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Dev Store: 8 / 8.4 mps&lt;/li&gt;
&lt;li&gt;Files - 817 / 908 mps&lt;/li&gt;
&lt;li&gt;Memory - 14700 / 44000 mps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;First of all&lt;/strong&gt;, You shouldn't worry much about relatively slow performance of local Azure Queues (that's what happens when you use take the complex path). Production performance should be an order of magnitude faster for a single thread. Besides, File and Memory partitions were added precisely to compensate for this slow performance while reducing development friction for Windows Azure Platform.&lt;/p&gt;

&lt;p&gt;BTW, there is a chance that we can come up with better queues for Azure, than Azure Queues, drawing inspiration from &lt;a href="http://martinfowler.com/articles/lmax.html"&gt;LMAX circular architecture&lt;/a&gt; and relying on the inherent Lokad.CQRS capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;, while looking at Files/Memory performance on a single thread, I would say that this is not so bad for code that was not performance optimized for the sake of staying simple.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Caveat: this performance applies to local operations only. True tests should cover network scenario that matches your production development (preferably with a chaos monkey in the house).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Probably if we use RabbitMQ or ZeroMQ, throughput can be even better than files out-of-the box. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third&lt;/strong&gt;, performance improvement is just a side effect. This refactoring was actually driven by desire do simplify the core (potentially getting rid of IoC container), provide much better support for extremely simple handler composition (based on lambdas), event sourcing and strongly-typed pipes.&lt;/p&gt;

&lt;p&gt;For example, you can actually wrap all your command handlers (this applies even for polymorphic dispatch of commands/events) with some method that apply to them all (i.e.: logging, audit, auth etc). You can check this &lt;a href="http://skillsmatter.com/podcast/design-architecture/simple-is-better"&gt;video of Greg Young&lt;/a&gt; to get a hint of things where we are going from here.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=zlmTWYmYCEs:NqlUXsS12lY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=zlmTWYmYCEs:NqlUXsS12lY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=zlmTWYmYCEs:NqlUXsS12lY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=zlmTWYmYCEs:NqlUXsS12lY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=zlmTWYmYCEs:NqlUXsS12lY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.abdullin.com/~ff/Shared-Libraries?a=zlmTWYmYCEs:NqlUXsS12lY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Shared-Libraries?i=zlmTWYmYCEs:NqlUXsS12lY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Shared-Libraries/~4/zlmTWYmYCEs" height="1" width="1"/&gt;</content><feedburner:origLink>http://abdullin.com/journal/2011/7/17/lokadcqrs-getting-simpler-and-faster.html</feedburner:origLink></entry></feed>

