<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.rabdullin.com/~d/styles/itemcontent.css"?><!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Thu, 24 May 2012 00:51:04 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Rinat Abdullin on Efficient Software Development</title><link>http://abdullin.com/journal/</link><description>Articles on efficient software development with .NET, including IoC, ORM, Cloud Computing.</description><lastBuildDate>Tue, 22 May 2012 08:37:08 +0000</lastBuildDate><copyright /><language>en-US</language><generator>Squarespace Site Server v5.11.81 (http://www.squarespace.com/)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.rabdullin.com/RinatAbdullin" /><feedburner:info uri="rinatabdullin" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>RinatAbdullin</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>DDD/CQRS Challenge - Integrating Distributed Systems</title><category>CQRS</category><category>Cloud Computing</category><category>DDD</category><category>Lokad</category><category>Story</category><category>xLim</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Tue, 22 May 2012 08:37:06 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/7svSemKeNGc/dddcqrs-challenge-integrating-distributed-systems.html</link><guid isPermaLink="false">287483:2929700:16387861</guid><description>&lt;p&gt;Let's have a look at the relatively simple DDD/CQRS challenge in &lt;strong&gt;integrating elements of a distributed system&lt;/strong&gt; composed of a &lt;em&gt;different bounded contexts&lt;/em&gt; and deployed across &lt;em&gt;different hosting environments&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's imagine a small Software-as-a-Service company which provides some subscription-based service while charging customers per consumption on pay-as-you-go basis. Software infrastructure of such company could consist of only 3 bounded contexts (a major oversimplification on my part, bigger view might be &lt;a href="http://abdullin.com/journal/2012/4/7/birds-eye-view-of-a-distributed-system-context-map.html"&gt;more complicated&lt;/a&gt;):&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/05/2012-05-22_100843.jpg?__SQUARESPACE_CACHEVERSION=1337674187688" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subscriptions&lt;/strong&gt; - subscription management system, that keeps track of all customers, their active plans, billing information, invoices, monthly service consumption and available login keys. This system is architected as NoSQL solution with event sourcing and is deployed on a dedicated server (with plans to redeploy it to Azure some time later).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Services Integration&lt;/strong&gt; - massively scalable set of services deployed in Windows Azure (e.g. using some &lt;a href="http://abdullin.com/journal/2012/5/2/processing-big-data-in-cloud-a-la-lokad.html"&gt;big data processing design&lt;/a&gt;). Among the other things, these services expose API to 3rd party companies and even products of the same company. This API is secured by user tokens, which are replicated from the subscriptions BC. This project is stable and does not change frequently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Product 1&lt;/strong&gt; - a new product being delivered by the company. It is developed as a standalone set of systems that enhance user experience, using Cloud API. This product leverages authentication and user management capabilities from "Subscriptions" and interoperates with API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some examples of the interactions between these system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If new user is added to the subscriptions, it's auth credentials should be immediately (within 1-2 seconds) replicated to Cloud Services, to enable access via API.&lt;/li&gt;
&lt;li&gt;If customer's account is locked out due to balance overdraft, then all related users should be locked out of the API.&lt;/li&gt;
&lt;li&gt;When services consumption is detected in the API, it should be within 5 minutes reported to subscriptions portal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Naturally all &lt;strong&gt;these systems have to work independently&lt;/strong&gt; in such way, that if one of these is down, the rest will continue doing their part (at the very least by providing read-only UI, at best - doing everything that is not dependent on the other systems). &lt;/p&gt;

&lt;p&gt;For example, if subscriptions are down for maintenance or Cloud Services and Product 1 should continue working as they were (all pending changes should be replicated after system comes back online).&lt;/p&gt;

&lt;p&gt;Additional constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resulting design (with inherent implications) should be relatively easy to explain to a Junior dev.&lt;/li&gt;
&lt;li&gt;It should also be relatively straightforward to deploy and run systems both locally (xcopy deployment of .NET code) and in the cloud.&lt;/li&gt;
&lt;li&gt;systems should be able to change independently and rapidly as they follow their individual DDD evolution paths (for example, weekly releases with &lt;a href="http://abdullin.com/journal/2012/4/21/ddd-evolving-business-processes-a-la-lokad.html"&gt;new business processes&lt;/a&gt; but without breaking any relations).&lt;/li&gt;
&lt;li&gt;no more than 3 people per project to develop and maintain it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note, that we are focusing here only on the integration between the systems. Internal design of each system might affect such integration, but is less relevant in this case. Still it would be nice, if integration patterns shared natural affinity with internal design of each bounded context (this tends to create systems that are more robust and practical).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How would you approach this problem?&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=7svSemKeNGc:97dN6dvXsko:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=7svSemKeNGc:97dN6dvXsko:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=7svSemKeNGc:97dN6dvXsko:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=7svSemKeNGc:97dN6dvXsko:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=7svSemKeNGc:97dN6dvXsko:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=7svSemKeNGc:97dN6dvXsko:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/7svSemKeNGc" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16387861.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/5/22/dddcqrs-challenge-integrating-distributed-systems.html</feedburner:origLink></item><item><title>DDD Summit 2012 Summary - #DDDesign</title><category>CQRS</category><category>DDD</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Sun, 20 May 2012 12:30:41 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/VMBh3oFS-fA/ddd-summit-2012-summary-dddesign.html</link><guid isPermaLink="false">287483:2929700:16352147</guid><description>&lt;p&gt;Some time ago I was honored (probably because of some sheer mistake) to be invited to &lt;strong&gt;DDD Summit 2012&lt;/strong&gt; organized by Eric Evans. The event took place in Portland over the course of last week and it was an absolute blast for me. &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/05/2012-05-20-DDD-Summit-2012.jpg?__SQUARESPACE_CACHEVERSION=1337508439593" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;From left to right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cameron Purdy&lt;/strong&gt; - VP of development at Oracle [&lt;a href="http://www.jroller.com/cpurdy/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/cpurdy"&gt;twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Daniel Gackle&lt;/strong&gt; - CoFounder at &lt;a href="http://www.crunchbase.com/company/skysheet"&gt;SkySheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Randy Stafford&lt;/strong&gt; - A-Team at Oracle [&lt;a href="http://c2.com/cgi/wiki?RandyStafford"&gt;About&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jimmy Nilsson&lt;/strong&gt; - Factor10, Author of Applying DDD Design and Patterns [&lt;a href="http://jimmynilsson.com/blog/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/JimmyNilsson"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rebecca Wirfs-Brock&lt;/strong&gt; - &lt;a href="http://www.wirfs-brock.com/"&gt;Wirfs-Brock&lt;/a&gt; and Responsibility-Driven Design [&lt;a href="http://en.wikipedia.org/wiki/Rebecca_Wirfs-Brock"&gt;Wiki&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vaughn Vernon&lt;/strong&gt; - Consultant at ShiftMethod, Author of the next DDD Book [&lt;a href="http://vaughnvernon.co/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/vaughnvernon"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Andreas Brink&lt;/strong&gt; - Software developer &amp;amp; coach at Factor10 [&lt;a href="http://blog.andreasbrink.se/#home"&gt;Blog&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alberto Brandolini&lt;/strong&gt; - &lt;a href="http://www.avanscoperta.it/site/"&gt;Avanscoperta&lt;/a&gt;, DDD Instructor and master of tomato [&lt;a href="http://ziobrando.blogspot.fr/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/ziobrando"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eric Evans&lt;/strong&gt; - Father of DDD and founder of &lt;a href="http://www.domainlanguage.com/"&gt;Domain Language&lt;/a&gt; [&lt;a href="https://twitter.com/#!/ericevans0"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dan Bergh Johnsson&lt;/strong&gt; - consultant and partner at OmegaPoint [&lt;a href="http://dearjunior.blogspot.fr/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/danbjson"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paul Rayner&lt;/strong&gt; - DDD Instructor at Domain Language [&lt;a href="https://twitter.com/#!/thepaulrayner"&gt;Twitter&lt;/a&gt;, &lt;a href="http://www.virtual-genius.com/blog/"&gt;Blog&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Martin Fowler&lt;/strong&gt; - needs no introductions [&lt;a href="http://en.wikipedia.org/wiki/Martin_Fowler"&gt;Wiki&lt;/a&gt;, &lt;a href="https://twitter.com/#!/martinfowler"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patrik Fredriksson&lt;/strong&gt; - Consultant at Citerus AB, DDD Instructor  [&lt;a href="http://weakreference.blogspot.fr/"&gt;Blog&lt;/a&gt;, &lt;a href="https://twitter.com/#!/weakreference"&gt;Twitter&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rinat Abdullin&lt;/strong&gt; - accidental visitor, Tech Leader of &lt;a href="http://www.lokad.com/"&gt;Lokad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In essence, we were discussing various aspects of DDD in small focus groups and all together, going out on hikes and dinners, talking, talking and talking. There was a wide variety of topics covered during these three days.&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/05/2012-05-20-DDD-topics.jpg?__SQUARESPACE_CACHEVERSION=1337508869497" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For me, this was an amazing opportunity to dive deeper into DDD nuances, practical experience and ideas shared by the leading thought leaders.&lt;/p&gt;

&lt;h2&gt;Outcomes and Commitments&lt;/h2&gt;

&lt;p&gt;Long story made short, there are some outcomes of this event that should benefit of the community (including some of my personal commitments).&lt;/p&gt;

&lt;p&gt;There is going to be &lt;strong&gt;more activity&lt;/strong&gt; on the &lt;a href="http://dddcommunity.org/"&gt;DDDCommunity.org site&lt;/a&gt;, that might have felt a little neglected over the course of last year (with a lot of good materials being hidden by accident). Things will start improving within the next few weeks (more regular updates and more structured community).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I personally hope to contribute some small practical experience bits of community building from projects and groups on DDD/CQRS (i.e. &lt;a href="http://cqrsguide.com/"&gt;CQRSGuide&lt;/a&gt; and CQRS Beers with awesome communities around EU) , &lt;a href="http://lokad.github.com/"&gt;Lokad projects&lt;/a&gt; and &lt;a href="http://distributedpodcast.com/"&gt;Distributed Podcast&lt;/a&gt;, maybe even bringing all these closer together.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Practical samples&lt;/strong&gt; are a big thing for demonstrating DDD. We plan to bring them together on a github and refresh a little bit (may be even adding Scala/Akka implementation!). &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;My own &lt;a href="http://lokad.github.com/lokad-cqrs/"&gt;Lokad.CQRS Sample Project&lt;/a&gt; is essentially a sample of DDD (with all the latest tech stack, cloud portability, practical things and even some DDD modeling toolset) that currently lacks the most important thing - proper domain model. I plan to fix this last problem by the mid of June, in addition to committing to things I've been delaying far too long (i.e.: articles and videos about the sample project).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;More articles and materials&lt;/strong&gt; about the Domain-Driven Design are expected be published; some of the topics were already outlined by the summit participants. There are plans to establish better environment for reviewing and shepherding such materials, which should definitely help.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I personally plan to &lt;a href="http://abdullin.com/posts/"&gt;continue writing&lt;/a&gt; about various aspects of DDD/CQRS+ES. Hopefully these new articles will start making slightly more sense due to focus not only on disposable technical details (which CQRS+ES is, despite all its coolness and cloud-portability), but also on strategic and design decisions governed by DDD. Besides, some more peer pressure is expected on them :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are even more cool long-term plans about pushing DDD and state of the art in the community, however they are long-term. Meanwhile, you can stay tuned for the updates via &lt;a href="https://twitter.com/#!/search/%23DDDesign"&gt;#DDDesign&lt;/a&gt; (I'll make sure that any official DDDCommunity news will be auto-published on twitter via this tag as well).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How does this look?&lt;/em&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VMBh3oFS-fA:SL_KxoA0MxE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=VMBh3oFS-fA:SL_KxoA0MxE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VMBh3oFS-fA:SL_KxoA0MxE:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VMBh3oFS-fA:SL_KxoA0MxE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VMBh3oFS-fA:SL_KxoA0MxE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=VMBh3oFS-fA:SL_KxoA0MxE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/VMBh3oFS-fA" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16352147.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/5/20/ddd-summit-2012-summary-dddesign.html</feedburner:origLink></item><item><title>Dark Visual Studio Theme</title><dc:creator>Rinat Abdullin</dc:creator><pubDate>Tue, 08 May 2012 07:25:36 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/Uwgcvof1Uis/dark-visual-studio-theme.html</link><guid isPermaLink="false">287483:2929700:16171299</guid><description>&lt;p&gt;This is for those of you who were asking about the color scheme used in my Visual Studio and 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/05/2012-05-08_themes.png?__SQUARESPACE_CACHEVERSION=1336461107402" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="http://abdullin.com/storage/uploads/2012/05/2012-05-08-DarkColors.zip"&gt;DarkColors.zip&lt;/a&gt; with explanations below.&lt;/p&gt;

&lt;p&gt;For text editor I'm using dark version of amazing color scheme &lt;a href="http://ethanschoonover.com/solarized"&gt;Solarized by Ethan Schoonover&lt;/a&gt;, which was slightly adapted to play nicely with R# formatting (see &lt;code&gt;Exported-Fonts-and-colors.vssettings&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Tabs and window elements in Visual Studio were adjusted by Theme Manager Package for Visual Studio. I used theme derived from &lt;code&gt;Elite Dark&lt;/code&gt;. My windows console actually uses Console2 manager hosting bash. Color settings are stored in xml files, I provided mine for the reference in &lt;code&gt;Settings-for-console2.xml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I find these color settings to less constraining for the eyes in various lighting conditions.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=Uwgcvof1Uis:w_DqPw3gwg8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=Uwgcvof1Uis:w_DqPw3gwg8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=Uwgcvof1Uis:w_DqPw3gwg8:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=Uwgcvof1Uis:w_DqPw3gwg8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=Uwgcvof1Uis:w_DqPw3gwg8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=Uwgcvof1Uis:w_DqPw3gwg8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/Uwgcvof1Uis" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16171299.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/5/8/dark-visual-studio-theme.html</feedburner:origLink></item><item><title>Move Forward by Discarding Complex Tech</title><category>Lokad</category><category>xLim</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Sat, 05 May 2012 04:53:56 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/VuiC37AJ6mE/move-forward-by-discarding-complex-tech.html</link><guid isPermaLink="false">287483:2929700:16133630</guid><description>&lt;p&gt;Good things are either well-forgotten past or a complete rip-off from the nature. It seems that at Lokad we are going all the way back in time ourselves as well.&lt;/p&gt;

&lt;p&gt;Over the course of the last few days we had really interesting times at Ufa office, while &lt;strong&gt;migrating entire event replication infrastructure to a new model&lt;/strong&gt;. If you wish, you can call this infrastructure as &lt;em&gt;bounded context of digital nervous system&lt;/em&gt; that is represented by &lt;a href="http://abdullin.com/journal/2012/4/7/birds-eye-view-of-a-distributed-system-context-map.html"&gt;green arrows in our context maps&lt;/a&gt;. This is a really interesting place for us, since it "touches" multiple other bounded contexts and actually crosses 2 clouds and 1 additional datacenter deployment-wise. Change shocks are mesmerizing to observe. &lt;/p&gt;

&lt;p&gt;Now, instead of a mixture of Azure queue delivery and ZeroMQ streaming, our applications just &lt;strong&gt;push large event streams over hand-made HTTP replication protocol&lt;/strong&gt;. This effectively uses HttpListener and WebRequests, which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rather performant;&lt;/li&gt;
&lt;li&gt;dead-simple and well understood;&lt;/li&gt;
&lt;li&gt;have minimal friction of introducing replication to new projects (ZeroMQ is pretty invasive here, if you go for Azure);&lt;/li&gt;
&lt;li&gt;can be debugged with a lot of HTTP-based tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design is rather simple, practical and works well for streams of half a million of events (albeit performance could be improved a lot). This was really important, since we have now a number of bounded contexts to integrate together and the volume of event streams just keeps on growing.&lt;/p&gt;

&lt;p&gt;It is curious, how our movement forward towards better and simpler designs happens concurrently with &lt;strong&gt;stepping back from complex technologies to much simpler ones&lt;/strong&gt;. In other words, we &lt;strong&gt;gain by discarding things&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Another example of such behavior is related to our recent decision to &lt;strong&gt;discard ProtoBuf as the storage format for large data objects&lt;/strong&gt;, while &lt;strong&gt;replacing ProtoBuf+Gzip with TSV+Gzip&lt;/strong&gt;. This applies specifically to &lt;a href="http://abdullin.com/journal/2012/5/2/processing-big-data-in-cloud-a-la-lokad.html"&gt;bounded contexts that deal with big data&lt;/a&gt;. Reasons for that being:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ProtoBuf by default loads all objects directly into the memory at once (imagine a dataset of 1 GB), while the default behavior of text files is streaming;&lt;/li&gt;
&lt;li&gt;For numerical data TSV+Gzip compresses better than ProtoBuf+Gzip, since archivers were initially designed and optimized specifically for handling text data;&lt;/li&gt;
&lt;li&gt;You can read and parse TSV dataset with tools on any platform, including scripts and Excel. While with protobuf, some intermediate dancing would be required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if I can reduce a number of technologies in a given bounded context, while making it more practical and performant, then that's a clear choice.&lt;/p&gt;

&lt;p&gt;As you can see, &lt;strong&gt;in certain scenarios&lt;/strong&gt;, we are stepping back from cool and smart tech towards something more practical and simple. This "stepping back" actually enables us to solve certain problems that exist in this specific scenario. Surprisingly enough, this brings us closer to the Unix philosophy: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I certainly didn't expect to see this happening before, not even theoretically. However, &lt;strong&gt;in practice, there is a big difference between theory and practice&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;Caveats&lt;/h2&gt;

&lt;p&gt;Please, keep in mind, that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we are aware of ProtoBuf capability to read items sequentially.&lt;/li&gt;
&lt;li&gt;we still will be using ProtoBuf for serializing messages, including events that are used for our event sourcing scenarios (leveraging for .NET development a wonderful library by &lt;a href="http://code.google.com/p/protobuf-net/"&gt;Marc Gravell&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;these examples just serve the purpose of illustrating possibility of cases, where you can move forward by discarding a technology. Specific decisions might not be applicable directly to your case.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VuiC37AJ6mE:S2Js63Ci3X4:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=VuiC37AJ6mE:S2Js63Ci3X4:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VuiC37AJ6mE:S2Js63Ci3X4:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VuiC37AJ6mE:S2Js63Ci3X4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=VuiC37AJ6mE:S2Js63Ci3X4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=VuiC37AJ6mE:S2Js63Ci3X4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/VuiC37AJ6mE" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16133630.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/5/5/move-forward-by-discarding-complex-tech.html</feedburner:origLink></item><item><title>Processing Big Data in Cloud à la Lokad</title><category>Azure</category><category>C#</category><category>CQRS</category><category>Cloud Computing</category><category>DDD</category><category>Event Sourcing</category><category>Lokad</category><category>Story</category><category>xLim</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Tue, 01 May 2012 20:36:07 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/RYQMIsXoDNk/processing-big-data-in-cloud-a-la-lokad.html</link><guid isPermaLink="false">287483:2929700:16082214</guid><description>&lt;p&gt;Let's talk about a simple approach to visualise, model and deliver complex large-scale data processing tasks.  Such tasks would deal with datasets that are so large, that they don't fit into the memory of a single machine and would also take ages to compute on a single machine. These datasets can often be referred to as "BigData".&lt;/p&gt;

&lt;p&gt;Such tasks would benefit from distributing out the work and storage load between relatively cheap machine instances that are made available in the cloud (either public or "private"). We would also want to optimize our consumption costs by get these resources only when they are needed and releasing afterwards.&lt;/p&gt;

&lt;p&gt;Let's also assume that such processing task, requires &lt;strong&gt;complex sequence of steps in order to complete&lt;/strong&gt; (more complex than a mere MapReduce). Some steps must be processed before others can start, while others can work in parallel batches. Actual steps of the job are idempotent, messages can be delivered more than once or simply fail. &lt;/p&gt;

&lt;p&gt;Here is an example of how such processing graph could look 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/2012/05/2012-05-02_graph.jpg?__SQUARESPACE_CACHEVERSION=1335899043937" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;That's how I would approach such problem in the situation, when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;development resources are limited;&lt;/li&gt;
&lt;li&gt;data processing model is not formally established and is likely to evolve;&lt;/li&gt;
&lt;li&gt;team (or a single developer) is familiar with event sourcing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would split the problem domain into two separate bounded contexts: Orchestration and Data Processing.&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/05/2012-05-02_bigdata.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;Bounded Contexts&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Orchestration Bounded Context&lt;/strong&gt; will be responsible for navigating data processing graph and orchestrating the individual jobs. Behaviors for that will be captured inside an aggregate root that uses event sourcing for persistence (AR+ES) for better testing and getting persistence mismatch troubles out of the way. Deployment-wise, this aggregate can live in a separate machine and would be configured in such a way, that all commands to this aggregate are synchronized and executed on a single thread (just a routing rule for messages).&lt;/p&gt;

&lt;p&gt;AR+ES just schedules batches of tasks that can be executed an parallel, and issues second batch only when the first one is complete. &lt;/p&gt;

&lt;p&gt;Should there be any message duplication (always a possibility in the cloud environments), AR+ES can easily track and drop duplicates by keeping hashes of already completed task batch identifiers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Processing Bounded Context&lt;/strong&gt; will be implemented using a set of command handlers that consume work commands from an input queue and process them. These handlers would operate upon data that is stored somewhere in the cloud and is considered to be immutable for the duration of the specific big data process. Commands and events can contain meta-data, parameters and references to this immutable data.&lt;/p&gt;

&lt;p&gt;In essence, command handler is a function that will take as input a command (which could contain a reference to larde immutable data blob), perform certain operations and publish an event (optionally saving some large processing data into another data blob). &lt;/p&gt;

&lt;p&gt;Multiple instance of command handlers would be picking commands from the input queue in this bounded context. In essence, they would be competing for the jobs, just like clercs in the bank "compete" for customers standing in line (customer is handled by only one clerk). However, we would be better than a bank, since if we can always massively increase the number of command handlers handling the load, by instructing cloud fabric to provision more machines.&lt;/p&gt;

&lt;p&gt;Both bounded contexts subscribe to all important domain events of each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; we should differentiate between actual data (which is so large that it does not fit into a single machine/process) and behavioral metadata. The former is accessed only by data processing bounded context, while the latter is passed within the messages between both bounded contexts. For example, number of time series in dataset is metadata, while actual values within these time series are actual 'raw' data.&lt;/p&gt;

&lt;p&gt;Orchestration Aggregate would use that metadata to make decisions that 'drive' the process through the graph.&lt;/p&gt;

&lt;h2&gt;Flow of work&lt;/h2&gt;

&lt;p&gt;Let's say we have a &lt;code&gt;ProcessAggregate&lt;/code&gt; that contains orchestration logic for our complicated MapReduce process. When this aggregate starts, it simply publishes X events that say something&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TaskAScheduledEvent(processId = 1, taskID = guid)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; there is more elegant way to do this, but that would require going deeper into DDD&lt;/p&gt;

&lt;p&gt;These events would be received by Receptor (or Port) in the second bounded context, which would  translate them into instances of &lt;code&gt;ProcessTaskACommand&lt;/code&gt;. These command messages would be passed into the queue from which multiple worker machines pick their jobs. &lt;/p&gt;

&lt;p&gt;When command handler finishes processing the task it sends &lt;code&gt;TaskAProcessedEvent&lt;/code&gt;, which will get routed back to the &lt;code&gt;ProcessAggregate&lt;/code&gt; as &lt;code&gt;ConfirmTaskAResults(task ID = guid)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Within the aggregate we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mark task as confirmed (if it hasn't already been reported due to message duplication).&lt;/li&gt;
&lt;li&gt;If this task completes some batch and enables further processing, we schedule more tasks for cloud execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can also define a timeout view that simply lists all tasks that are currently running. Timeout manager (a simple process) regularly checks this view and sends "TryTimeoutTaskX" to the aggregate. Aggregate checks with it's internal state, and if task indeed has not been processed, decides to either reissue the task or terminate the whole process (yes, we essentially implement our timeout tracking as a &lt;a href="http://abdullin.com/journal/2012/4/21/ddd-evolving-business-processes-a-la-lokad.html"&gt;business process within Lokad.CQRS architecture style&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;Gotchas&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt; of this approach (esp. if aligned with Lokad.CQRS architecture style):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no need to worry about persistence of complex object that represents our graph decision logic;&lt;/li&gt;
&lt;li&gt;orchestration logic can be explicitly tested with the specifications (and documented as such);&lt;/li&gt;
&lt;li&gt;we can easily migrate between multiple versions of the data process without downtime or stopping processes;&lt;/li&gt;
&lt;li&gt;process can easily be developed and debugged on the local machine, while being deployed to any cloud afterwards;&lt;/li&gt;
&lt;li&gt;we use same approaches and ideas that are used within Lokad.CQRS architecture style for modeling more conventional business concepts (this lowers learning barrier and allows to reuse answers to some common problems).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Drawbacks&lt;/strong&gt; of this approach are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It requires certain development discipline (and familiarity with cloud computing and AR+ES);&lt;/li&gt;
&lt;li&gt;At the moment of writing, there is no prepackaged infrastructure for event sourcing that would work out-of-the-box;&lt;/li&gt;
&lt;li&gt;performance of this approach would be somewhat inferior to finely tuned functional style map-reduce process implementation;&lt;/li&gt;
&lt;li&gt;this is a batch-processing approach, which is not fit for real-time processing (yet).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, with this approach we trade some performance for development and deployment flexibility. This enables us to rapidly model and implement big data process (especially when requirements are still changing). After the process is formalized, we can always fine-tune and optimize bottlenecks. Although frequently you would find that it is cheaper to add another server (worth 100 EUR per month) than waste multiple development days of brilliant developers on performance optimizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heads up&lt;/strong&gt;: the entire infrastructure does not need to be really performant with one exception - if you are doing hundreds of thousands of messages within a single process, then it's worth to invest effort in messaging infrastructure (e.g. direct communication with ZeroMQ), otherwise latency will kill everything. Event stream for actual process aggregate can be simply cached in memory.&lt;/p&gt;

&lt;h2&gt;Deployment Options&lt;/h2&gt;

&lt;p&gt;Below are some deployment variations that could be used within this approach. We can implement our core processing logic without any coupling to specific deployment environment and then deploy in various configurations. The latter would require just re-configuration and optionally providing some specific adapters implementations (for messaging, event sourcing and large BLOB streaming).&lt;/p&gt;

&lt;p&gt;Alternatively you can have the same project prepared for multiple deployment options from the start.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local development machine:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orchestration bounded context runs as one thread;&lt;/li&gt;
&lt;li&gt;multiple data processing command handlers run either as parallel threads or as multiple instances of a single console app;&lt;/li&gt;
&lt;li&gt;file system is used for both message queueing, persistence of large binary files and event streams for aggregates.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Windows Azure Cloud:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orchestration bounded context runs in a single worker role (e.g. instance of Lokad.CQRS-based engine);&lt;/li&gt;
&lt;li&gt;data processing handlers run as additional Windows Azure worker roles (you can configure them to run on X different threads within Y worker role instances);&lt;/li&gt;
&lt;li&gt;Large data is streamed to Azure Blob Storage, just like event streams for AR+ES entities;&lt;/li&gt;
&lt;li&gt;Azure queues are used for messaging.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amazon Elastic Compute:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Orchestration bounded context is a single VM, while Data processing command handlers run within multiple replicas of another VM. We scale by adding or dropping instances of that second VM.&lt;/li&gt;
&lt;li&gt;Amazon S3 storage is used for persisting large binary data, while local instance of RabbitMQ is used for messaging; event streams could be persisted locally within orchestration VM.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obviously, these are just some of the few options. You can have completely different scenario, based on the specific resources, requirements, risks and constraints within you project.&lt;/p&gt;

&lt;p&gt;In each of these cases, elastic scaling can be done by implementing a simple task that would watch upon the amount of messages waiting in the command queue of data processing bounded context, adjusting number of command handler instances accordingly.&lt;/p&gt;

&lt;h2&gt;Final Words&lt;/h2&gt;

&lt;p&gt;This approach is in not a silver bullet. It just summarizes some limited experience gained while developing and maintaining non-realtime big data processes that could be hosted both in the cloud and on-premises. As such, it can have numerous applicability limitations (especially if you are working within constrained enterprise environment). Some alternative approaches and references worth mentioning are available in the &lt;a href="http://abdullin.com/journal/2012/2/13/reading-list-on-big-data.html"&gt;reading list on Big Data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, if you need to quickly deliver out some scalable multi-step data process with one person, no money for expensive software licenses and just a few weeks of time, then this approach might give you some ideas.&lt;/p&gt;

&lt;p&gt;If you want to read more along these lines, here are a few more relevant posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/journal/2012/3/31/anatomy-of-distributed-system-a-la-lokad.html"&gt;Anatomy of Distributed System à la Lokad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/journal/2012/4/7/birds-eye-view-of-a-distributed-system-context-map.html"&gt;Bird's-eye view of a Distributed System - Context Map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/journal/2012/4/14/software-war-starts-with-a-map-context-map.html"&gt;Software War Starts with a Map, Context Map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/journal/2012/4/17/ddd-from-reality-to-implementation.html"&gt;DDD: From Reality to Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://abdullin.com/journal/2012/4/21/ddd-evolving-business-processes-a-la-lokad.html"&gt;DDD: Evolving Business Processes a la Lokad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=RYQMIsXoDNk:qKPTcsBlwhA:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=RYQMIsXoDNk:qKPTcsBlwhA:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=RYQMIsXoDNk:qKPTcsBlwhA:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=RYQMIsXoDNk:qKPTcsBlwhA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=RYQMIsXoDNk:qKPTcsBlwhA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=RYQMIsXoDNk:qKPTcsBlwhA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/RYQMIsXoDNk" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16082214.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/5/2/processing-big-data-in-cloud-a-la-lokad.html</feedburner:origLink></item><item><title>Continuous Delivery with Lokad.CQRS</title><category>Azure</category><category>CQRS</category><category>Cloud Computing</category><category>DDD</category><category>Event Sourcing</category><category>Lokad</category><category>xLim</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Thu, 26 Apr 2012 12:02:45 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/iZyL2ZhCOgM/continuous-delivery-with-lokadcqrs.html</link><guid isPermaLink="false">287483:2929700:16008006</guid><description>&lt;p&gt;Today I was presenting at the Roots about Lokad.CQRS architecture style. As part of the presentation I created a quick deployment of Lokad sample project, tweaked for a continuous delivery scenario. &lt;/p&gt;

&lt;p&gt;In short, every time a change is pushed to &lt;code&gt;master&lt;/code&gt; within this repository: &lt;a href="https://github.com/abdullin/lokad-cqrs-appharbor"&gt;Lokad.CQRS-AppHarbor&lt;/a&gt;, AppHarbor performs a new full deployment of this site: &lt;a href="http://lokad-cqrs.apphb.com"&gt;http://lokad-cqrs.apphb.com&lt;/a&gt;. It is the duty of Lokad.CQRS to rebuild any projections that might have changed in the code.&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/04/2012-04-26_135941.jpg" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For the most fun: this deployment is actually about 2 clouds. AppHarbor (located within Amazon) deals with builds and hosting, while data is persisted on Azure. I just didn't have time to write adapters for the persistence available within the AppHarbor (the entire deployment thing was delivered within few litres of coffee and 6-8 man hours of work).&lt;/p&gt;

&lt;p&gt;Naturally, while working with the system within local development environment, persistence is based on dead-simple file storage.&lt;/p&gt;

&lt;p&gt;Currently this repository is an off-shot of latest Lokad.CQRS, created for the demo purposes. &lt;/p&gt;

&lt;p&gt;However, this experience enables totally new development approach by massively slashing down development friction. I'm tempted to push it to the master of Load.CQRS and keep it hooked with this continuous deployment, while maybe even adding more domain "meat" around inventory management concept. I think, some fun could be had around the process, where every accepted pull request is immediately deployed to production.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=iZyL2ZhCOgM:9k5NVMCLra0:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=iZyL2ZhCOgM:9k5NVMCLra0:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=iZyL2ZhCOgM:9k5NVMCLra0:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=iZyL2ZhCOgM:9k5NVMCLra0:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=iZyL2ZhCOgM:9k5NVMCLra0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=iZyL2ZhCOgM:9k5NVMCLra0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/iZyL2ZhCOgM" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-16008006.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/4/26/continuous-delivery-with-lokadcqrs.html</feedburner:origLink></item><item><title>DDD: Evolving Business Processes a la Lokad</title><category>CQRS</category><category>DDD</category><category>Event Sourcing</category><category>Lokad</category><category>Story</category><category>xLim</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Sat, 21 Apr 2012 08:46:30 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/cZytGnP2yDg/ddd-evolving-business-processes-a-la-lokad.html</link><guid isPermaLink="false">287483:2929700:15936568</guid><description>&lt;p&gt;As you already know, there are multiple ways to express any given core business concept in the code via domain modeling (we discussed this topic in &lt;a href="http://abdullin.com/journal/2012/4/17/ddd-from-reality-to-implementation.html"&gt;previous article&lt;/a&gt;). These ways  usually depend on the architecture style selected for the bounded context, in which we are currently working.&lt;/p&gt;

&lt;p&gt;For now, let's focus on one of such domain concepts: &lt;strong&gt;long-running business processes&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In a cloud-based SaaS company, we could have following business processes (among many other):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if invoice has a non-zero amount and was not paid within 15 days, then send customer a reminder.&lt;/li&gt;
&lt;li&gt;if customer balance stays below -5EUR for more than 30 days, then issue a lockdown.&lt;/li&gt;
&lt;li&gt;if distributed computing process has not finished processing all data batches within 1 hour, then restart it once (except cases, when it was already restarted - then issue a termination alert)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you probably already noticed, these &lt;strong&gt;examples share a few similarities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they are aware of the passing of time and deal with it;&lt;/li&gt;
&lt;li&gt;these processes express rather complex precondition that is based on current state of the system and leads to one or more &lt;code&gt;then&lt;/code&gt; outcomes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's assume that we are dealing with a distributed system, where information about current state is shared with events. In such case, our business process might resemble a piece from complex event processing and would look this from the logical perspective:&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/04/2012-04-21_bp-1.jpg?__SQUARESPACE_CACHEVERSION=1334996466613" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;How can we implement this "Business Process" box? There are multiple alternatives, depending on the architecture style you have chosen. &lt;/p&gt;

&lt;p&gt;For example, you can use a state machine, where each instance of state machine would correspond to a specific process instance that you are tracking. Events would then be used to navigate an instance of the state machine across the nodes. It will also use external timer service to send messages "to future" (where message is put on hold till certain time comes).&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/04/2012-04-21_bp-st.jpg?__SQUARESPACE_CACHEVERSION=1334997691189" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;State machines are good for formalized domains. You can learn more about such approaches in the materials provided by Gregory Young and Udi Dahan.&lt;/p&gt;

&lt;p&gt;However, when we are dealing with business processes, that are rich with fuzzy logic, uncertainty and also happen to evolve rapidly, then a more simple solution might be needed. Especially, when you have almost no development time to spare.&lt;/p&gt;

&lt;p&gt;What is the most simple solution in case with locking customer balance for overdrafts? For instance, we can project all events to a view, which will &lt;strong&gt;track&lt;/strong&gt; all active customers that used our services and went below the threshold at some point. Then our &lt;strong&gt;execution&lt;/strong&gt; will be responsible for regularly checking this view and sending "Lockdown" to every customer that had his balance below the threshold for too long.&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/04/2012-04-21_bp-2.jpg?__SQUARESPACE_CACHEVERSION=1334996503818" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This component would also need to keep in mind that certain customers require special handling and investigation before being locked out, while others can be locked right away. Naturally, these rules will be changing really often.&lt;/p&gt;

&lt;p&gt;What is the fastest and most flexible way to implement such component in a rapidly growing and changing environment? &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/04/2012-04-21_bp3.jpg?__SQUARESPACE_CACHEVERSION=1334996518303" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;You simply wire view to the UI, attach a button to send "lockdown command" and &lt;strong&gt;ask a person&lt;/strong&gt; from the business department to &lt;strong&gt;spend half an hour per week processing all late customers&lt;/strong&gt;. This will save dev department hours on implementing these complex execution rules, testing them and then changing (as business discovers new corner cases). Essentially we let the rules evolve and change in the environment that shapes them: in the minds of business managers.&lt;/p&gt;

&lt;p&gt;In other words, at this point &lt;strong&gt;we avoid large development effort with a little bit of human time&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Please, keep in mind, that once business processes are established and we have so many cases, that manually processing them takes too much time (that should be a profitable company by then), we can always &lt;strong&gt;rewrite these lockdown rules as a continuously running server-side task&lt;/strong&gt; (rules would be mostly established by then). We could still keep the projection and a corresponding view.&lt;/p&gt;

&lt;p&gt;At this point we &lt;strong&gt;invest a fixed amount of development to automate a large portion of manual work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This gradual evolution of business processes is currently the recommended approach within Lokad.CQRS architecture style for delivery of non-formalized and rapidly changing business rules.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=cZytGnP2yDg:qxnoG7f9wPE:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=cZytGnP2yDg:qxnoG7f9wPE:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=cZytGnP2yDg:qxnoG7f9wPE:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=cZytGnP2yDg:qxnoG7f9wPE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=cZytGnP2yDg:qxnoG7f9wPE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=cZytGnP2yDg:qxnoG7f9wPE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/cZytGnP2yDg" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-15936568.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/4/21/ddd-evolving-business-processes-a-la-lokad.html</feedburner:origLink></item><item><title>DDD: From Reality to Implementation</title><category>CQRS</category><category>Cloud Computing</category><category>DDD</category><category>Lokad</category><category>Story</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Tue, 17 Apr 2012 07:17:24 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/L-q8S7St46k/ddd-from-reality-to-implementation.html</link><guid isPermaLink="false">287483:2929700:15877947</guid><description>&lt;blockquote&gt;
  &lt;p&gt;This is yet another post in a series that were triggered by fruitful discussions with &lt;a href="http://vaughnvernon.co/"&gt;Vaughn Vernon&lt;/a&gt; over content for his DDD book.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think, one of the sources of confusion in DDD/CQRS world is that we often mix terms and concepts that belong do absolutely different layers (and that we don't know how to go from one to the other). Let's start by introducing the following separation:&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/04/2012-04-17_DDD-reality.jpg?__SQUARESPACE_CACHEVERSION=1334640831088" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For the new readers, DDD stands for Domain Driven Design, which was introduced by &lt;a href="http://domaindrivendesign.org/about"&gt;Eric Evans&lt;/a&gt; in the book with the same name. CQRS stands for Command-Query Responsibility Principle, which is often associated with architecture styles for implementing systems with DDD and optional Event Sourcing. The term was coined and explored by &lt;a href="http://goodenoughsoftware.net/"&gt;Greg Young&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Reality&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Reality&lt;/strong&gt; is that thing around us, which we perceive through our senses and continuously try to understand. In the context of business and software, &lt;strong&gt;reality contains core business concepts&lt;/strong&gt; which are important for the competitive advantage of our business. We want to capture them and then somehow express in code for automation purposes. For example, business concepts could involve things as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer&lt;/li&gt;
&lt;li&gt;Registration Process&lt;/li&gt;
&lt;li&gt;Customer Subscription&lt;/li&gt;
&lt;li&gt;Invoice&lt;/li&gt;
&lt;li&gt;Invoice Payment Cycle&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;I'm taking examples from the environment of Software-as-a-Service (SaaS) company, since that's what I'm mostly familiar with.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;Domain Model&lt;/h2&gt;

&lt;p&gt;As we learn more about reality and business concepts, we could distill our understanding into the &lt;strong&gt;domain model&lt;/strong&gt;, which contains all things that are relevant and important in the current situation. For the sake of simplicity, we will break down the entire model into set of bounded contexts (BCs) which are separate by the natural boundaries we've discovered in the real world.&lt;/p&gt;

&lt;p&gt;In SaaS world we could highlight BCs like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer Subscriptions and Billing&lt;/li&gt;
&lt;li&gt;Client Portal&lt;/li&gt;
&lt;li&gt;Reporting&lt;/li&gt;
&lt;li&gt;Product 1&lt;/li&gt;
&lt;li&gt;Product 2&lt;/li&gt;
&lt;li&gt;Cloud integration&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of the bounded contexts in this model stems directly from our understanding of the reality and the natural boundaries that we have identified (&lt;a href="http://abdullin.com/journal/2012/4/14/software-war-starts-with-a-map-context-map.html"&gt;read more&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;If we dive inside one of these bounded contexts, we could discover more fine-grained concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubiquitous Language&lt;/li&gt;
&lt;li&gt;Aggregate and Aggregate Root&lt;/li&gt;
&lt;li&gt;Consistency Boundary&lt;/li&gt;
&lt;li&gt;Business Process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please keep in mind, that these are purely logical concepts, that have (yet) nothing to do with the implementation and all the less important details!&lt;/p&gt;

&lt;p&gt;The process of identifying BC boundaries can take into consideration things like: teams, skills, available resources and technologies. However, &lt;strong&gt;at this level we still don't care about technical details like&lt;/strong&gt;: frameworks, databases, message middleware, service buses etc. We just create foundation for making conscious choice later down the road.&lt;/p&gt;

&lt;h2&gt;Architecture Styles and Implementation&lt;/h2&gt;

&lt;p&gt;Only after we have identified bounded contexts, we can focus on each BC and start thinking about implementation matters, while considering project specifics. Result of this exciting process would be a choice of key elements for the specific bounded context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;development process&lt;/strong&gt; - how do we organize and manage our development.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;architecture style&lt;/strong&gt; - how do we structure and design software implementation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;technology stack&lt;/strong&gt; - what technologies do we use and how do we get them&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resource allocation&lt;/strong&gt; - how do we get resources (budgets, people, knowledge) for the project delivery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For instance, if our teams are familiar with the SQL/RavenDB and NService Bus, we can pick &lt;strong&gt;architecture style described by Udi Dahan&lt;/strong&gt; (&lt;a href="http://www.udidahan.com/?blog=true"&gt;blog&lt;/a&gt;), where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aggregates are persisted with SQL+NHibernate or RavenDb;&lt;/li&gt;
&lt;li&gt;command handlers and application services are hosted by NServiceBus;&lt;/li&gt;
&lt;li&gt;business processes are implemented with NServiceBus sagas;&lt;/li&gt;
&lt;li&gt;consistency boundaries happen within the transaction scope;&lt;/li&gt;
&lt;li&gt;views are created either by in-memory events or via projected audit logs;&lt;/li&gt;
&lt;li&gt;development process will be aligned towards Waterfall or Agile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If environment requires event sourcing or teams are hyped with &lt;strong&gt;AR+ES architectural style of Greg Young&lt;/strong&gt; (&lt;a href="http://goodenoughsoftware.net/"&gt;blog&lt;/a&gt;), we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;persist aggregates with event sourcing in event streams;&lt;/li&gt;
&lt;li&gt;host command handlers in custom message dispatchers that use something like AMQP or direct socket communication;&lt;/li&gt;
&lt;li&gt;business processes are mainly implemented with state machines hosted within event handlers or via document-based state machines (where state is persisted in messages);&lt;/li&gt;
&lt;li&gt;views are disposable and are projected from event streams to whatever technology that is needed;&lt;/li&gt;
&lt;li&gt;consistency boundaries are within aggregate;&lt;/li&gt;
&lt;li&gt;use Agile development process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At Lokad we are mostly using &lt;strong&gt;Lokad.CQRS architecture style&lt;/strong&gt; (&lt;a href="http://lokad.github.com/lokad-cqrs/"&gt;sample&lt;/a&gt;) that is derived from Greg's but is fine-tuned to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fit cloud computing environments while supporting on-premises deployments;&lt;/li&gt;
&lt;li&gt;reduce development friction and development effort at the &lt;strong&gt;cost of higher requirements for team skills and discipline&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;support rapid domain evolution in rapidly changing business environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture style involves following technical choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aggregates are persisted with event sourcing in event stream;&lt;/li&gt;
&lt;li&gt;message handlers are hosted in custom message dispatchers provided by Lokad.CQRS sample project (with adapters for on-premises and cloud deployments);&lt;/li&gt;
&lt;li&gt;business process transitions are implemented as part of the aggregate behaviors (they could be triggered by user interactions, stateless event handlers sending commands in response to events or tasks that sending commands on a schedule);&lt;/li&gt;
&lt;li&gt;views are disposable and are projected from event streams, using dead-simple key-value persistence for the majority of cases (with adapters for on-premises and cloud);&lt;/li&gt;
&lt;li&gt;consistency boundaries are per entity (aggregate or view instance);&lt;/li&gt;
&lt;li&gt;rapid development process is used for multiple releases per week/day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obviously, these are just a few options of implementing a given bounded context. There are more architecture styles available out there (and each architecture style can have multiple implementation options and variations).&lt;/p&gt;

&lt;h2&gt;DDD Modeling Process&lt;/h2&gt;

&lt;p&gt;Now, for the most fun part. This trajectory from reality to architectural style is just a &lt;em&gt;happy path scenario&lt;/em&gt; that happens only in dreams. In reality you might need to &lt;strong&gt;iterate from reality to implementation multiple times&lt;/strong&gt;:&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/04/2012-04-17_DDD-iterate.jpg?__SQUARESPACE_CACHEVERSION=1334644192048" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;These iterations are the foundation of the &lt;strong&gt;approach to explore and capture core business concepts in domain model&lt;/strong&gt; (or, one of the approaches). Approach is totally attributed to Greg Young. &lt;/p&gt;

&lt;p&gt;We start by sketching out domain model without even trying hard to be precise from the start. Then we try to implement it in the code using the &lt;strong&gt;most hacky approach possible&lt;/strong&gt;. Lokad.CQRS style with file-based persistence and messaging works for us, because it is designed for rapid iterations and has the least friction (I'll need to do a quick video on that process). &lt;/p&gt;

&lt;p&gt;One of the goals here is to build a set of unit tests that use &lt;a href="http://cqrsguide.com/doc:specification"&gt;specifications&lt;/a&gt; to verify behaviors of aggregate roots with event sourcing (AR+ES). These specifications can be printed out as use cases in human-readable way.&lt;/p&gt;

&lt;p&gt;More often than not, a lot of problems and questions show up during this implementation phase. At this point we usually forget about the implementation (while keeping our use cases) and go back to the domain experts with these questions (more often than not, for me this boils to going and talking to the mirror). Then we adjust the domain model according to the lessons learned. Depending on the nature of the adjustment, implementation is either discarded completely or refactored to fit (AR+ES specifications are usually kept between these iterations, to make sure that we don't loose any captured use case).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;process is repeated till we distill our domain model&lt;/strong&gt; to the point that it captures all required business concepts in a way that can be easily implemented in the code. At this point we can print out specifications, reconfigure implementation to use adapters for production environment (e.g. Azure), push it to production and try to call it a day (only to have next challenge handed to us).&lt;/p&gt;

&lt;p&gt;PS: If you are interested in this topic, next article in the series might interest you: &lt;a href="http://abdullin.com/journal/2012/4/21/ddd-evolving-business-processes-a-la-lokad.html"&gt;DDD: Evolving Business Processes a la Lokad&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=L-q8S7St46k:o2qcDhspnvQ:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=L-q8S7St46k:o2qcDhspnvQ:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=L-q8S7St46k:o2qcDhspnvQ:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=L-q8S7St46k:o2qcDhspnvQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=L-q8S7St46k:o2qcDhspnvQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=L-q8S7St46k:o2qcDhspnvQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/L-q8S7St46k" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-15877947.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/4/17/ddd-from-reality-to-implementation.html</feedburner:origLink></item><item><title>Lokad.CQRS Architecture Style: Plans and Boundary</title><category>Azure</category><category>Cloud Computing</category><category>Event Sourcing</category><category>Lokad</category><category>Story</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Sun, 15 Apr 2012 09:11:46 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/5fG0CmkkfnQ/lokadcqrs-architecture-style-plans-and-boundary.html</link><guid isPermaLink="false">287483:2929700:15853164</guid><description>&lt;blockquote&gt;
  &lt;p&gt;Все фигня, кроме пчел, да и пчелы - тоже фигня (c) &lt;br /&gt;
  &lt;strong&gt;Ответ старого пчеловода на вопрос о смысле жизни&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the course of last few months I was lead to a simple realization: &lt;strong&gt;CQRS/ES is not a top-level architectural style, but rather a tactical choice&lt;/strong&gt;. Yes, I know that this is what people have been talking about for all the time; but hearing is one thing, while understanding is the other.&lt;/p&gt;

&lt;p&gt;This simple realization makes CQRS/ES much less important on the big picture (or maybe my own picture just got bigger). So, when we have a complex problem at hand, we start by identifying natural boundaries around some core business concepts, which would let us identify separate bounded concepts. Only then we can decide about architectural styles that could be applied within a specific bounded contexts. (I went into more detail on that in my &lt;a href="http://abdullin.com/journal/2012/4/14/software-war-starts-with-a-map-context-map.html"&gt;last post&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lokad.github.com/lokad-cqrs/"&gt;Lokad.CQRS&lt;/a&gt; (in it's current anatomy branch on github) is currently a &lt;strong&gt;sample project demonstrating my favorite way of implementing bounded contexts&lt;/strong&gt; that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rich in business behavior;&lt;/li&gt;
&lt;li&gt;require rapid changes and releases (we are rapidly learning about environment);&lt;/li&gt;
&lt;li&gt;require elastic scalability and ability to be deployed to various cloud environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a sharp tool, that requires discipline as well as people with certain knowledge and experience. On the bright side - it is verified by practical experience, cloud outages and startup environment.&lt;/p&gt;

&lt;p&gt;As you can see, we've just defined &lt;strong&gt;applicability boundaries of Lokad.CQRS+ES approach&lt;/strong&gt;. This actually helps it to focus and stop attempts to handle all possible scenarios. The approach works and &lt;strong&gt;I don't plan a lot of changes any time soon&lt;/strong&gt; (maybe just more documentation and tooling improvements). &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;My current friction points currently reside on a higher level - making multiple bounded contexts (that are deployed across clouds and datacenters) to work together. Especially, when you have a rapidly growing software-as-a-service company that tends to introduce multiple services and changes per year; where each one brings new bounded contexts and details on the global strategy map (and these guys just don't know how to stop).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once again, I'm happy with the current state of Lokad.CQRS architecture style and don't expect a lot of changes to it. CQRSGuide will probably gradually transition into a documentation guide across that specific architecture style. &lt;/p&gt;

&lt;p&gt;Please keep in mind, that this approach is just one of many out there. There are two other options in .NET world that I want to highlight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NServiceBus and things that &lt;a href="http://www.udidahan.com/"&gt;Udi Dahan teaches&lt;/a&gt;. I might have strong personal disapproval of values and grounds of his approaches, however they work in world's largest companies. You can't argue with that.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cqrsjourney.github.com/"&gt;Microsoft CQRS P&amp;amp;P Journey&lt;/a&gt;, which has a strong technical team with a diverse advisory group. In my opinion they are focusing too much on debates and less important technical things, but the progress Microsoft is making is impressive. I wish them luck.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested in pushing state of the art in this area, I encourage you to &lt;strong&gt;dive deeper, learn and share what you have learned&lt;/strong&gt;. It does not matter, which project you would choose for that - you will gain and give a lot either way.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=5fG0CmkkfnQ:xw-Ye9MesoM:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=5fG0CmkkfnQ:xw-Ye9MesoM:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=5fG0CmkkfnQ:xw-Ye9MesoM:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=5fG0CmkkfnQ:xw-Ye9MesoM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=5fG0CmkkfnQ:xw-Ye9MesoM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=5fG0CmkkfnQ:xw-Ye9MesoM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/5fG0CmkkfnQ" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-15853164.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/4/15/lokadcqrs-architecture-style-plans-and-boundary.html</feedburner:origLink></item><item><title>Software War Starts with a Map, Context Map</title><category>DDD</category><category>Lokad</category><category>Story</category><dc:creator>Rinat Abdullin</dc:creator><pubDate>Sat, 14 Apr 2012 11:49:03 +0000</pubDate><link>http://feeds.rabdullin.com/~r/RinatAbdullin/~3/2l-PgSy_7I0/software-war-starts-with-a-map-context-map.html</link><guid isPermaLink="false">287483:2929700:15823709</guid><description>&lt;blockquote&gt;
  &lt;p&gt;Let us continue revisiting the big picture overview of all DDD and CQRS things, based on the things I've learned recently in collaboration with &lt;a href="http://goodenoughsoftware.net/"&gt;Gregory Young&lt;/a&gt; and &lt;a href="http://vaughnvernon.co/"&gt;Vaughn Vernon&lt;/a&gt;. We will start with the most important things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's imagine that you are a software manager challenged with a new project to deliver. The project is really interesting and challenging, customer can talk about it for hours. Sometimes there will be references to similar projects to copy and cool technologies that should help. You and your team are already itching to start flush out some specs and start developing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it really where you start?&lt;/strong&gt; Wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complex software project is a war&lt;/strong&gt; - it is unpredictable and brutal fight to hit moving target, while always running short on time and resources.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;NB: I'm currently talking about "startup" environments. Enterprise situations with available resources and preallocated budgets are a different story that we are not interested right now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You don't enter software war with low-level details. You don't start with detailed tech specifications or strategies (unless you want to have perfectly planned and failed &lt;em&gt;blitzkrieg&lt;/em&gt; on your hands). First &lt;strong&gt;you need a strategic map&lt;/strong&gt; with bird's-eye view of the current situation at hand. Maybe this war is not even worth entering?&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/04/2012-04-13_russia.png?__SQUARESPACE_CACHEVERSION=1334292365690" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;One of the approaches of getting such map is to make your way through "Domain-Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans (just make sure to read it this way: chapter 11 - END; Beginning - END).&lt;/p&gt;

&lt;p&gt;Domain Driven Design (DDD) is a special way to look at core business concepts that exist in a real world and deeply connect them to evolving domain model, that could be easily implemented in software to solve specific problems. In other words, it can help to look at real world, understand it and divide into a set of separate territories that can be conquered separately, step by step.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“One step at a time, ... I can walk around the world. Watch me.” (c) L.M.Bujold&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Separate territories are called "&lt;em&gt;bounded contexts&lt;/em&gt;", while the big map is called "&lt;em&gt;context map&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;We use DDD toolset (set of rules, hints and guidelines) to look at the complex mess of important business concepts and identify natural boundaries around some of them. These natural boundaries would be discovered in the real world and then transferred to our "context map". Area within the boundary will be called "bounded context"&lt;/p&gt;

&lt;p&gt;This process is equivalent to geography or geology, where explorers map the terrain and draw borders around areas that look the same according to some arbitrary criteria. Criteria for finding such natural boundaries can be extremely different and will depend on your situation (synonym to "situation" is "context"). As it has always been: drawing maps is a challenge, especially when half of the territory is terra incognita (or covered by the "fog of war").&lt;/p&gt;

&lt;p&gt;Please keep in mind, that Context Map is not a plan of some distant future. It is merely a reflection of current situation that we have in our software project or a company. It is a map of terrain that has to stay updated and real, in order to be of any use.&lt;/p&gt;

&lt;p&gt;Let me be clear: you don't necessarily need to map all the terrain of software project on a context map, before starting to work on it (sometimes research and development is the only way to move forward). However, &lt;strong&gt;staying aware of the business situation&lt;/strong&gt; (context), uncharted areas, and potential unknown risks, &lt;strong&gt;will make you more prepared for unexpected changes&lt;/strong&gt; in the future. Being able to divide complex problem area into a set of separate bounded contexts will make it easier to think through the situation and approach it.&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/04/2012-04-07_context-map-2.png" alt=""/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The biggest advantage of separate bounded contexts is about their explicit separation from each other. &lt;strong&gt;Once we have clear boundaries, we can consciously focus on the situation inside&lt;/strong&gt; in relevant isolation. For each specific context within a boundary, we can pick the most efficient combination of technologies, teams and development approaches.&lt;/p&gt;

&lt;p&gt;For example, given a SaaS battlefield and a new secret "Product XYZ", the latter could allow division into two separate bounded contexts. One specific bounded context (highly complicated and requiring special approach) can be handled by a special research and development team, while the other neightboring BC could be delegated to a team specializing in solving diverse and messy situations.&lt;/p&gt;

&lt;p&gt;As you can already see, our context map not only allows to start tackling problem space, but also enable considering the allocation of limited resources over a seemingly endless battlefield of possible projects to deal with. Same works with risk mitigation, time and long-term campaign planning. At certain moments in the course of software war, you can even identify situations, where certain projects could be worth a sacrifice, risky spike, massive refactoring (or all of these at once).&lt;/p&gt;

&lt;p&gt;It might be really boring to read all this text without any mention of cool technologies (e.g. self-rebuilding CQRS view projection host with unlimited scalability for reads), however &lt;strong&gt;technology choices are mostly irrelevant on a higher level&lt;/strong&gt;. Technology or an architecture style can be an enabling factor or even a strategic asset, but they are never the ones that drive the campaign.&lt;/p&gt;

&lt;p&gt;One of the best places to learn such things in practice is by working in a startup. Such places tend to have rapidly changing battlefield and rather low tolerance for stupid decisions. In war of startups you win or you die.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=2l-PgSy_7I0:SFBdVktn7z8:-BTjWOF_DHI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=2l-PgSy_7I0:SFBdVktn7z8:-BTjWOF_DHI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=2l-PgSy_7I0:SFBdVktn7z8:nQ_hWtDbxek"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=nQ_hWtDbxek" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=2l-PgSy_7I0:SFBdVktn7z8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.rabdullin.com/~ff/RinatAbdullin?a=2l-PgSy_7I0:SFBdVktn7z8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RinatAbdullin?i=2l-PgSy_7I0:SFBdVktn7z8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RinatAbdullin/~4/2l-PgSy_7I0" height="1" width="1"/&gt;</description><wfw:commentRss>http://abdullin.com/journal/rss-comments-entry-15823709.xml</wfw:commentRss><feedburner:origLink>http://abdullin.com/journal/2012/4/14/software-war-starts-with-a-map-context-map.html</feedburner:origLink></item></channel></rss>

