<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Patterson&#039;s Blog</title>
	<atom:link href="http://lostechies.com/chrispatterson/feed/" rel="self" type="application/rss+xml" />
	<link>http://lostechies.com/chrispatterson</link>
	<description>Just another LosTechies site</description>
	<lastBuildDate>Wed, 11 Apr 2012 16:16:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Odoyule Rules Engine for .NET</title>
		<link>http://lostechies.com/chrispatterson/2012/04/11/odoyule-rules-engine-for-net/</link>
		<comments>http://lostechies.com/chrispatterson/2012/04/11/odoyule-rules-engine-for-net/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 16:16:16 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[.net]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=85</guid>
		<description><![CDATA[So I&#8217;ve been writing a rules engine for .NET for many years (on and off, but mostly off unfortunately). Lately, I picked it up again and yesterday published an early version on NuGet (OdoyuleRules). The implementation at this point is&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2012/04/11/odoyule-rules-engine-for-net/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been writing a rules engine for .NET for many years (on and off, but mostly off unfortunately). Lately, I picked it up again and yesterday published an early version on NuGet (OdoyuleRules). The implementation at this point is capable of pretty extensive matching, but testing is light at this point so there are probably some rough edges.</p>
<p>One of my favorite features is the visualization of the RETE graph once the engine has been loaded with rules. An example is shown below.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://blog.phatboyg.com/wp-content/uploads/2012/04/OdoyuleRulesVisualization.png" border="0" alt="OdoyuleRulesVisualization" width="640" height="305" /></p>
<p> </p>
<p>You can download the Visualizer and install it in Visual Studio 2010 (unzip the contents to your My Document/Visual Studio 2010/Visualizers folder). Then, mouse over a reference to a rules engine while debugging and you should be able to select and display the RETE graph of the engine.</p>
<p>Download the visualizer assemblies here: <a title="OdoyuleRulesVisualizer.zip" href="http://blog.phatboyg.com/wp-content/uploads/2012/04/OdoyuleRulesVisualizer.zip">OdoyuleRulesVisualizer.zip</a></p>
<p>The project is hosted on GitHub, at <a href="http://phatboyg.github.com/OdoyuleRules">http://phatboyg.github.com/OdoyuleRules</a></p>
<p>Enjoy!</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2012/04/11/odoyule-rules-engine-for-net/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>References on the Actor Programming Model</title>
		<link>http://lostechies.com/chrispatterson/2011/11/26/references-on-the-actor-programming-model/</link>
		<comments>http://lostechies.com/chrispatterson/2011/11/26/references-on-the-actor-programming-model/#comments</comments>
		<pubDate>Sat, 26 Nov 2011 20:22:56 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=83</guid>
		<description><![CDATA[The actor programming model is a software development method that encourages the decomposition of applications into autonomous components which are self-contained and operate asynchronously and independently from one another. This model is well aligned with the nondeterministic nature of distributed&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2011/11/26/references-on-the-actor-programming-model/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The actor programming model is a software development method that encourages the decomposition of applications into autonomous components which are self-contained and operate asynchronously and independently from one another. This model is well aligned with the nondeterministic nature of distributed systems, including mobile systems, interactive systems, and the internet.</p>
<p>As I mentioned previously, I didn&#8217;t invent it. I&#8217;m merely leveraging the information obtained from a number of sources and applying it in a way that I think makes it easier to build certain types of applications. Applications that can benefit from a highly concurrent actor-based programming model include reactive systems &#8212; ones that respond to nondeterministic external events. Since many applications can be described as &#8220;a program that responds to external events&#8221; it only makes sense that the actor programming model can be applied to many domains.</p>
<p>Here are some papers that I&#8217;ve read on the actor model, some of which have influenced me in how I think about concurrent programming and others that have merely provided background information or depicted ways in which concurrent programming should not be approached.</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=actors%20rajesh%20karmani&amp;source=web&amp;cd=5&amp;ved=0CD8QFjAE&amp;url=http%3A%2F%2Fwww.cs.ucla.edu%2F~palsberg%2Fcourse%2Fcs239%2Fpapers%2Fkarmani-agha.pdf&amp;ei=1EjRToveNYTo2QW8jL2fDw&amp;usg=AFQjCNFGRhp1lee0PTWR-P-zoZh53PlPPg">Actors</a>, Rajesh K. Karmani, Gul Agha</p>
<p><a href="http://hdl.handle.net/1721.1/1692">Actors: A Model of Concurrent Computation In Distributed Systems</a>, Gul A. Agha (out of print)</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=actor%20languages%20for%20specification%20of%20parallel%20computations&amp;source=web&amp;cd=2&amp;sqi=2&amp;ved=0CCcQFjAB&amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.54.8636%26rep%3Drep1%26type%3Dpdf&amp;ei=yUTRTsagJ-Gi2gWq--ySDw&amp;usg=AFQjCNG9xXGsndDiaOg4e1IXmidFT6_QyA">Actor Languages for Specification of Parallel Computations</a>, Gul Agha, Wooyoung Kim, Rajendra Panwar</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CCwQFjAA&amp;url=http%3A%2F%2Fosl.cs.illinois.edu%2Fdocs%2Fhp92%2Fhp.pdf&amp;ei=OEbRTvPvKILS2gXg3cy6Dw&amp;usg=AFQjCNHnqFN88E0QqQhuMq8hIWvJXMlJbQ">An Actor-Based Framework for Heterogeneous Computing Systems</a>, Gul Agha, Rajendra Panwar</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CB0QFjAA&amp;url=http%3A%2F%2Flamp.epfl.ch%2F~phaller%2Fdoc%2Fhaller07actorsunify.pdf&amp;ei=dkbRTsjhEKrs2AXi96nMDw&amp;usg=AFQjCNEGCiUihzxt1xrjfocx_qanRATegw">Actors that Unify Threads and Events</a>, Philipp Haller, Martin Odersky</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;ved=0CCAQFjAA&amp;url=http%3A%2F%2Flamp.epfl.ch%2F~phaller%2Fdoc%2Fhaller10-Translucent_functions.pdf&amp;ei=qkbRToTHIsWC2wXUsrmaDw&amp;usg=AFQjCNHfk44fbCGvf3ZDzI0BLkfNxITyDA">Lightweight Language Support for Type-Based, Concurrent Event Processing</a>, Philipp Haller</p>
<p><a href="http://www.google.com/url?sa=t&amp;rct=j&amp;q=compilation%20of%20a%20highly%20parallel%20actor-based%20language&amp;source=web&amp;cd=3&amp;sqi=2&amp;ved=0CDUQFjAC&amp;url=http%3A%2F%2Fosl.cs.illinois.edu%2Fdocs%2Fhal-compilation92%2Fhal-compilation.pdf&amp;ei=TEnRTrbUK6Hq2QXarNm1Dw&amp;usg=AFQjCNFRI9bn7Cl-b8AkWmcIceFl5kQ8tQ">Compilation of a Highly Parallel Actor-Based Language</a>, WooYoung Kim, Gul Agha</p>
<p>These are some of the more involved works from which I&#8217;ve found many useful bits of information. I&#8217;ve got them permanently stored in <a href="http://www.goodiware.com/goodreader.html">GoodReader</a> so I can keep looking back to them (and my associated annotations as well). Hopefully anyone looking to build systems using the actor model (and hopefully, using Stact if you&#8217;re on the .NET platform) can get a better understanding of the model by reviewing these papers.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2011/11/26/references-on-the-actor-programming-model/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MassTransit v2.0.1 Available</title>
		<link>http://lostechies.com/chrispatterson/2011/11/16/masstransit-v2-0-1-available/</link>
		<comments>http://lostechies.com/chrispatterson/2011/11/16/masstransit-v2-0-1-available/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 14:28:49 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=80</guid>
		<description><![CDATA[At the end of October, we released MassTransit v2.0.1 to GitHub and NuGet. This release only included a few fixes that didn&#8217;t make it into the v2.0 release. Since I never made an official announcement of v2.0 on the blog,&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2011/11/16/masstransit-v2-0-1-available/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At the end of October, we released MassTransit v2.0.1 to GitHub and NuGet. This release only included a few fixes that didn&#8217;t make it into the v2.0 release. Since I never made an official announcement of v2.0 on the blog, some links to the project, documentation, and mailing list are included below.</p>
<p>For those using the 1.x lineage of MassTransit, v2.0 includes several breaking changes in the API. This was necessary to reduce the complexity of getting new users up-to-speed, as well as eliminating some common areas of confusion. The API for v2.x should remain consistent from this point forward (well, until we start working on v3.x, which is a long ways off honestly).</p>
<p><a href="https://github.com/MassTransit/MassTransit">Project Site (hosted on GitHub)<br /></a><a href="http://nuget.org/List/Packages/MassTransit">NuGet Project</a><br /><a href="http://docs.masstransit-project.com/en/latest/index.html">Documentation</a><br /><a href="http://groups.google.com/group/masstransit-discuss">Mailing List</a><br /><a href="http://www.ohloh.net/p/masstransit">Ohloh Metrics</a></p>
<p>It&#8217;s worth noting that the MassTransit organization on GitHub is the &#8216;official&#8217; repository. Please file any issues on that repository so that all of the MassTransit team members can help with any issues. However, you are encouraged to check the mailing list first as many first-time issues are discussed there.</p>
<p>This release was a long road and involved a lot of internal code cleanup, API grooming, and support for a new transport (RabbitMQ). We welcome your feedback, questions, and suggestions.</p>
<p>Enjoy!</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2011/11/16/masstransit-v2-0-1-available/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Actor Model Programming in C#</title>
		<link>http://lostechies.com/chrispatterson/2011/11/15/actor-model-programming-in-c/</link>
		<comments>http://lostechies.com/chrispatterson/2011/11/15/actor-model-programming-in-c/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 16:22:46 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[concurrency]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=78</guid>
		<description><![CDATA[Last week, I had the pleasure of attending Øredev in Malmö, Sweden. While at the conference, I presented two sessions &#8212; including a new talk on Actor Model Programming in C#. This was the first official presentation I&#8217;ve given on&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2011/11/15/actor-model-programming-in-c/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Last week, I had the pleasure of attending <a href="http://oredev.org/2011">Øredev</a> in Malmö, Sweden. While at the conference, I presented two sessions &#8212; including a new talk on <a href="http://oredev.org/2011/sessions/actor-model-programming-in-c-">Actor Model Programming in C#</a>. This was the first official presentation I&#8217;ve given on the subject, having done an ad-hoc version of the session at <a href="http://pablosfiesta.pbworks.com/w/page/46324025/Actor%20Style%20Programming">Pablo&#8217;s Fiesta</a> this year (which went fairly well, likely due to the awesome <a href="http://24diner.com/wp-content/uploads/2011/02/waffle_staff.jpg">Chicken and Waffles</a> at <a href="http://24diner.com/">24 Diner</a> the night before). Early feedback from the Øredev session was positive, which is encouraging since I will be giving an updated version of the talk at CodeMash 2.0.1.2 in January.</p>
<p>First, I wanted to share a few links to the content discussed in the session, including the <a href="http://github.com/phatboyg/Stact">GitHub Project</a>, the <a href="http://nuget.org/List/Packages/Stact">NuGet package</a>, and the <a href="http://teamcity.codebetter.com/viewType.html?buildTypeId=bt258&amp;tab=buildTypeStatusDiv">TeamCity build</a>. I will update the post with the video link once the presentation video is available, along with the slide deck.</p>
<p>Second, I plan to post a series of blog posts explaining how actor model programming is a great model for building concurrent applications, despite the difficulties that the actor model has had in becoming more mainstream (some of those difficulties are explaining in <a href="http://www.doc.ic.ac.uk/~nd/surprise_97/journal/vol2/pjm2/">this article by Paul Mackay</a>).</p>
<p>In the meantime, I&#8217;m going to take a hard look at how different languages have implemented the actor model (many of which have influenced the current syntax used in Stact). I&#8217;m also taking a step back and identifying other ways the model can be implemented the minimize many of the difficulties and bring some modern programming style to the model. Concurrency is certainly difficult, but I&#8217;m convinced that many aspects can be made more approachable by applying some existing idioms to the problem.</p>
<p>If you do take a look at Stact, please offer any feedback you have via Twitter (I&#8217;m <a href="https://twitter.com/#!/phatboyg">@PhatBoyG</a>) or GitHub (using issues, whatever). If the traffic grows, we&#8217;ll setup a Google group to keep things manageable.</p>
<p>Until next time&#8230;</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2011/11/15/actor-model-programming-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>MassTransit v2.0 Beta Available Now on NuGet!</title>
		<link>http://lostechies.com/chrispatterson/2011/05/03/masstransit-v2-0-beta-available-now-on-nuget/</link>
		<comments>http://lostechies.com/chrispatterson/2011/05/03/masstransit-v2-0-beta-available-now-on-nuget/#comments</comments>
		<pubDate>Wed, 04 May 2011 02:48:17 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[masstransit]]></category>
		<category><![CDATA[msmq]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=75</guid>
		<description><![CDATA[After what seems like a long slumber, along with work being done on other projects such as Topshelf and Stact, it is our great pleasure to announce the first beta release of MassTransit v2.0. What originally started out as a&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2011/05/03/masstransit-v2-0-beta-available-now-on-nuget/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div>
<p>After what seems like a long slumber, along with work being done on other projects such as Topshelf and Stact, it is our great pleasure to announce the first beta release of MassTransit v2.0. What originally started out as a minor “1.3” update has turned into a full-out cleanup of the codebase, including a refinement of the configuration API. Since there were some breaking changes to the configuration, we felt a 2.0 moniker was better to ensure users of the framework understood the depth of the changes made.</p>
<p>And what a list of changes it is (TL;DR = We filled it with awesomeness): </p>
<ol>
<li>
<p>Configuration <br />MassTransit v2.0 now includes a streamlined configuration model built around an extensible fluent interface (inspired by Stact and Topshelf and sharing a common, consistent design). As a result, getting started with MassTransit is now easier than ever. In version 2.0, all configuration starts with the <em>ServiceBusFactory</em> and Intellisense guides you from there forward. The result is a clean, understandable API and a quicker out-of-the-box experience.</p>
</li>
<li>
<p>Container-Free Support<br />With the release of MassTransit 2.0, using a dependency injection container is now <strong>optional</strong>. When we started MassTransit, we leveraged the container extensively to assemble the internal workings of the bus. As we added support for other containers, required features that were not supported by a particular container led to some creative solutions (read: hacks) that were less than optimal. By moving away from a “container-first” approach, we have increased the reliability of the software and now provide container-specific extensions to subscribe consumers from the container in one simple step. We also threw in support for Autofac!</p>
</li>
<li>
<p>Quick-Start<br />By simplifying the configuration, and dropping the need for a container, it is now fast and easy to get started using our new QuickStart:<br /><a href="http://docs.masstransit-project.com/en/latest/configuration/quickstart.html">http://docs.masstransit-project.com/en/latest/configuration/quickstart.html</a></p>
</li>
<li>
<p>#NuGet<br /><a href="http://nuget.org/List/Search?packageType=Packages&amp;searchCategory=All+Categories&amp;searchTerm=MassTransit&amp;sortOrder=package-download-count&amp;pageSize=10">NuGet packages have been added for the base MassTransit</a> project, with any external dependencies (log4net and Magnum) resolved using the proper NuGet packages. Any additional references are downstream in additional NuGet packages, such as support for persisting sagas using NHibernate (MassTransit.NHibernate), and the various dependency injection containers supported.</p>
</li>
<li>
<p>Multiple Subscription Service Options<br />In addition to the existing <em>RuntimeServices</em> included with MassTransit, an all-new peer-to-peer subscription service has been added. By leveraging the reliable multi-cast support in MSMQ, services can now exchange subscription information without the need for a centralized subscription service. To ensure everything is setup correctly, a <em>VerifyMsmqConfiguration</em> method has been added that will check the installation of MSMQ and install any missing components. This is the first iteration of multi-cast support, and we need to get some mileage on it. In the meantime, the original run-time services continue to work as expected.</p>
</li>
<li>
<p>Documentation<br />Which brings us to the next big update. DOCS! They’re not perfect, and they’re far from complete, but we have focused on the configuration story to help get you up and running. As we see a need for more documentation in a given area, we will continue to flush out the docs appropriately. The docs are located at <a href="http://docs.masstransit-project.com/">http://docs.masstransit-project.com/</a> and are being hosted by the fine people at <a href="http://readthedocs.org/">http://readthedocs.org</a>. [Thanks <a href="http://ericholscher.com/">Eric</a>!]</p>
</li>
<li>
<p>Support for .NET 4.0 and .NET 3.5<br />The project files and solution have all been updated to Visual Studio 2010 SP1. By default, all projects are now built in the IDE targeting .NET 4.0. The command-line build (which has been revamped to use Rake and Albacore) builds both .NET 3.5 and .NET 4.0 assemblies, including the run-time services and System View. The NuGet packages also include the proper bindings for the target project run-time version (you must use the <strong>full .NET 4.0 profile</strong> with MassTransit, the client profile is not supported). </p>
</li>
<li>
<p>Transport Support<br />Internally, the transports and endpoints have been redesigned to improve the support for new transports like RabbitMQ (and improve our ActiveMQ support). For example, transports are now inbound, outbound, or both, allowing us to properly leverage fan-out exchanges on RabbitMQ for publishing and subscribing to messages. There is more to come in this area as we take greater advantage of these advanced transport features. If you’re a RabbitMQ or ActiveMQ user and don’t mind getting your hands dirty, now is a great time to jump in and help improve transport support.</p>
</li>
<li>
<p>Distributor Consumer And Saga Support<br />Work on the MassTransit distributor subsystem continues to be improved. Testing on a multi-master system has been completed which will allow it to serve multiple distributors to improve load balancing efficiency. Support for all sagas (previously only state machine sagas were supported) has been added as well.</p>
</li>
<li>
<p>Swinging the Feature Axe<br />Some previous troublesome and poorly supported features (Batching and Message Grouping) were removed from the 2.0 release to reduce code complexity. Also in light of the new Parallel Tasks work in the framework the Parallel namespace has been removed.</p>
</li>
</ol>
<p>In the next few days, I&#8217;ll be posting an annotated walkthrough of the new configuration API. In the meantime, fire up Visual Studio 2010, create ConsoleApplication69, switch to the full .NET 4.0 framework, and Add a Library Package Reference to MassTransit using NuGet. Paste the code from the <a href="http://docs.masstransit-project.com/en/latest/configuration/quickstart.html">Quick Start</a> into your program.cs and check it out!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2011/05/03/masstransit-v2-0-beta-available-now-on-nuget/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Right Tool, The Right Time</title>
		<link>http://lostechies.com/chrispatterson/2011/03/24/the-right-tool-the-right-time/</link>
		<comments>http://lostechies.com/chrispatterson/2011/03/24/the-right-tool-the-right-time/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 19:44:28 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://lostechies.com/chrispatterson/?p=68</guid>
		<description><![CDATA[Over the past few months I have been reviewing many of the products I was involved in creating, both as a developer and an architect, and have assembled an inventory of the technology and architecture used. With a catalog of products&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2011/03/24/the-right-tool-the-right-time/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over the past few months I have been reviewing many of the products I was involved in creating, both as a developer and an architect, and have assembled an inventory of the technology and architecture used. With a catalog of products spanning more than eighteen years, a diverse set of architectural styles are represented. On one end of the spectrum are client/server systems deployed on-premise and on the opposite end are software-as-a-service (SAAS) browser-based products. Most of these products are line-of-business systems and include both heavy user interaction and background data processing. In fact, two separate products offer a similar feature set targeted at the same market but sit on opposite ends of the architectural spectrum. The first product was built in the 90&#8242;s and is a client/server system, the latter was built more recently during the SAAS era targeting the web.</p>
<p>What follows are a few of the common design choices that I encountered, with my take on how appropriate that same choice would be today.</p>
<h2>Data Storage</h2>
<p>As I looked into each product, I examined how various requirements were addressed given the tools available at the time. For example, I didn&#8217;t question the use of a flat file to store reference data in the early client/server products since flat files were perfectly acceptable at the time. However, this led me to question some design choices when looking at SAAS products &#8212; including some choices that you might not expect. For instance, why is a flat file not an acceptable design choice for a system developed today? The data is still the same reference data, yet current guidance would suggest this reference data be stored in a database, most likely a relational database.</p>
<p>Is this because developers have become too lazy to write the component to read the file? Surely not, since a component will have to be written to import the reference data into the database. While it can be done fairly easily using database tools, the process still has to be scripted out and repeatable in case the import needs to be repeated on a new database.</p>
<p>Let&#8217;s enhance the problem and add a time dimension to the reference data, making updates available every thirty days. Now, not only is an initial import needed, but the import component will also need to support updating the database with the new content. Again, this could be done using database tools &#8212; a simple truncate table and repeat the import process. But what if developers have created relationships between the reference data table and other tables in the system? What if those relationships were created using the row id instead of the appropriate business identifier? At that point, the table cannot be simply truncated and the update process must now perform a complete delta of the existing and updated data sets and merge the changes into the database. That certainly doesn&#8217;t sound lazy &#8212; if anything, it sounds downright painful.</p>
<p>Another question that came to mind when using a relational database to store reference data was &#8220;which database?&#8221; Now, if the first answer that popped into your head when you read that was &#8220;SQL Server,&#8221; or even worse &#8220;the database,&#8221; therein lies the real problem.</p>
<p>A product is not just an application, it is a system composed of one or more applications, multiple components, multiple services, <strong>and multiple databases</strong>. Consider the earlier example that used a flat file to store reference data. The flat file itself <strong>is</strong> a separate database. In a system of any complexity there are many different sets of reference data, all of which are stored in their own separate flat files. Therefore, the system has multiple databases, each using the appropriate technology based on how that database is used.</p>
<p>If the reference data had remained in a flat file, when the flat file was updated with the new reference data, the original file is simply replaced and the system continues. No special import or update process is required.</p>
<h2>Nested Object Graphs</h2>
<p>Another common design I saw, particularly in products that manage a revolving set of accounts, was the use of a deeply nested object graph that is persisted in a relational database. As accounts were accessed, the entire object graph would be loaded from the database and presented to the user. Once the user made whatever changes were necessary at the time, the account was then saved to the database. In order to save the object graph, the nodes at each level in the graph are compared with the database, and deltas are generated to update the database tables.</p>
<p>In early examples of this design, a pessimistic locking system was implemented to track user activity and prevent multiple users from working on the same account at the same time. This was common in the client/server products, since even at that time record locking using ISAM files (or even network file locking) was fairly problematic.</p>
<p>As products moved to the web, a more optimistic locking strategy was used. I found two different conflict resolution methods, the first of which used a timestamp to track modifications to an account. If an update was received and the timestamp didn&#8217;t match, the later update was rejected. The second method was &#8220;last write wins,&#8221; updating the account to whatever was in the later update &#8212; possibly and quite commonly losing previous updates from other users. This got real interesting when two updates were performed at the same time.</p>
<p>Neither of these solutions make sense today for SAAS applications. In an environment where multiple users may be interacting with an account at the same time, it&#8217;s more important to look at providing users with a task-based user interface that captures the intent of each action on an account. For example, loading an entire account just to change the billing address creates unnecessary data movement that can limit throughput (read: scalability concern). At the same time, preventing a user from adding a charge to an account because another user slipped in behind you to update the phone number creates an unnecessary user burden. If updating the billing address, updating the phone number, and adding a charge to an account were explicit actions (read: commands) that can be performed on an account, they could all be performed simultaneously without conflict.</p>
<p><em>Note that the Command-Query Responsibility Segregation (CQRS) or even just Command-Query Separation (CQS) architectural styles specifically addresses this type of design.</em></p>
<h2>Stored Procedures</h2>
<p>In the example above, a deeply nested object graph was loaded from the database. In a system designed today, a developer would most likely reach for an object-relational mapper (ORM) to deal with loading and saving the object graph to the database. There are many to choose from (Hibernate, NHibernate, and Entity Framework are a few) and they solve the problem of binding object graphs to relational database tables very well. In fact, most ORMs today can generate the DDL needed to create the database objects as well &#8212; eliminating the need to write table creation scripts by hand.</p>
<p>At this point, I can hear the blood pressure of many database administrators reading this rising through the roof. With SQL book in hand and years of experience writing stored procedures full of selects and cursors, the story of how a hand tuned stored procedure that returns a sequence of forward-only record sets in a single round trip to the database server is the only way the scalability requirements of the application can be met. I&#8217;m not saying that using a stored procedure in this situation is wrong, but making a stored procedure the first tool you pull out the toolbox is very wrong indeed.</p>
<p>Why is it wrong? Creating a stored procedure to read data as the first approach is wrong because it is an optimization. Optimizing components of a system before that particular component has been identified as a bottleneck will lead to increased complexity, and that complexity will breed quickly in the project. And as complexity increases across the project, long term maintainability suffers as the capabilities of the development team are challenged. Yep, you guessed it, the stored procedure first approach is a classic case of premature optimization.</p>
<p>How does using a stored procedure in this way breed complexity? First of all, it establishes a myth that reads are a problem. As functionality is added to the system, developers who have come to believe that any account related reads must be done with a stored procedure else they become responsible for performance inadequacy, create more read procedures. As features continue to be implemented, more data elements are added to the schema, requiring every stored procedure to be updated as the schema changes &#8212; creating more work for developers who must now touch features that were complete and tested to ensure they still operate as expected.</p>
<p>The opposite effect of the read myth is that retrieving the entire object graph for an account is so well optimized that it is better to load the entire object and use only the needed data elements rather than create a new read procedure. With an ORM, this is handled very well using projections and fetching strategies. Developers can use the ORM to read a partial object graph, returning on the required data elements and reducing the data movement between the database and application server.</p>
<p>All of this accidental complexity was created based on the superstition that only a stored procedure would be fast enough to support the scalability needs of the product. An optimization that was implemented before a bottleneck was identified.</p>
<p>Considering that most ORMs today are capable of writing very efficient SQL and have dialects specifically tuned for each database platform, the read performance of the ORM is less likely to be a system bottleneck. For example, with Microsoft SQL Server, NHibernate takes advantage of batch queries with ADO.NET to reduce the number of round trips between the database and application servers. The SQL generated is also parameterized, allowing the SQL engine to cache execution plans for better server performance. Given these optimizations have already been done by the ORM, tuning read performance in the database is not likely to create the biggest benefit in system scalability. For example, caching of already loaded objects will likely result in greater overall read performance.</p>
<p><em>Did I forget to mention that this early decision tightly coupled the product to using a particular database platform? SQL dialects are hardly portable between platforms, so the product now has to decide if it will work with a single platform or create a separate release branch for each database platform supported. The better ORMs support multiple server dialects, including Microsoft SQL Server, Oracle, MySQL, PostgreSQL, and many others.</em></p>
<p>I said I wouldn&#8217;t argue the performance difference between using an ORM and a stored procedure. I will point out, however, that using a stored procedure to tune performance is an <strong>optimization</strong> for a particular environment and should not be an early choice in system design. Going straight for the stored procedure without considering less complex options is another case where a lot of times, the tool we used yesterday is not always appropriate for a system being designed today.</p>
<h2>To Be Continued&#8230;</h2>
<p>Above I&#8217;ve covered a few of the design choices made early in the development of several major products and how that affected the evolution of the product over time as featured were added. I also applied a modern view of how many of the choices we made before all these &#8220;great tools&#8221; were available are not necessarily bad today. As I get more time, I hope to share a few more stories with you as I undercover them in what has basically become a &#8220;career retrospective&#8221; for me.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2011/03/24/the-right-tool-the-right-time/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MassTransit Update</title>
		<link>http://lostechies.com/chrispatterson/2010/05/04/masstransit-update/</link>
		<comments>http://lostechies.com/chrispatterson/2010/05/04/masstransit-update/#comments</comments>
		<pubDate>Tue, 04 May 2010 20:56:07 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[masstransit]]></category>

		<guid isPermaLink="false">/blogs/chris_patterson/archive/2010/05/04/masstransit-update.aspx</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve posted about MassTransit, the .NET distributed application framework and service bus that Dru Sellers, myself, and several other contributors have been working on for the past 2.5 years. This is mostly due to a&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2010/05/04/masstransit-update/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
It&#8217;s been a while since I&#8217;ve posted about MassTransit, the .NET distributed application framework and service bus that Dru Sellers, myself, and several other contributors have been working on for the past 2.5 years. This is mostly due to a pretty heavy schedule in the first quarter (CodeMash, the MVP Summit, Pablo&#8217;s Fiesta, the North Dallas .NET User Group, and having an in-ground swimming pool built), along with a lot of exploratory coding on some new features for the framework.
</p>
<p>
While traveling to community events, it&#8217;s amazing to run into folks that are using MassTransit in their applications &#8212; particularly ones that I&#8217;ve never heard from before. It&#8217;s a cool feeling to know that people are finding value in the effort we&#8217;ve put into it. Over the past few months, several organizations have been finalizing the testing of new applications built on top of MassTransit, taking advantage of the state-driven saga support (including the new distributor for load balancing saga instances across servers), in preparation for production launches. Several contributors have offered tremendous help with this new functionality, including development of and testing with the distributor support.
</p>
<p>
It is great to see users of the framework taking an active role in shaping the feature set to meet a more generalized set of requirements. When Dru and I started creating MassTransit, we had a fairly narrow feature set that needed to be implemented. As the use of messaging in our applications expanded, we started to identify new features that would provide additional benefits. Being able to harvest application-specific code into the framework has provided a high level of reuse which helps everyone.
</p>
<h3>GitHub</h3>
<p>
The biggest move that we made in the past few months was leaving GoogleCode behind and migrating the project to <a href="http://github.com/phatboyg">GitHub</a>. If you have not yet discovered it yet, Git is an amazing distributed version control system that offers tremendous flexibility when working on highly distributed projects, such as open source projects. Combined with the amazing social collaboration that occurs on GitHub, we have merged significantly more features from contributors on GitHub in the past few months than we had previously received the entire time we were hosted at GoogleCode. Many have forked the <a href="http://github.com/phatboyg/MassTransit">main project</a> (which is hosted on <a href="http://github.com/phatboyg">my GitHub account</a>, and is also used to drive <a href="http://teamcity.codebetter.com/project.html?projectId=project6&amp;tab=projectOverview">the official builds</a> on the CodeBetter TeamCity server) and made changes that I have merged into the main project.
</p>
<p>
You can still download a compressed archive of the latest source from GitHub by clicking the <a href="http://github.com/phatboyg/MassTransit">download source</a> link on the <a href="http://github.com/phatboyg/MassTransit">project source</a> page. You can also <a href="http://teamcity.codebetter.com/viewType.html?buildTypeId=bt8&amp;tab=buildTypeStatusDiv">download the latest build</a> (or the <a href="http://teamcity.codebetter.com/viewLog.html?buildId=10337&amp;buildTypeId=bt8&amp;tab=artifacts">tagged v1.0 build</a>) from the TeamCity artifacts link. The build runs automatically when code is push to GitHub, so the latest build is always from the latest bits in the master branch.
</p>
<h3>Major Milestone</h3>
<p>
On March 1st, we marked a v1.0 release candidate of <a href="http://masstransit-project.com/">MassTransit</a> (and the related projects <a href="http://topshelf-project.com/">Topshelf</a> and <a href="http://magnum-project.net/">Magnum</a>). With open source projects there is always a syndrome of 0.x, where many projects never reach 1.0 yet are still used in production systems at multiple organizations. Considering the number of organizations using MassTransit (and even Topshelf by itself for hosting Windows services), we decided it was time to mark the release 1.0 and freeze the feature set for that line of the codebase.
</p>
<p>
Since the 1.0 release candidate, there has been very little active development on the MassTransit codebase. The reason for this is simple, we wanted to allow the framework a little time to soak into the community. There are a lot of features that we want to put into the framework, and several of these are under heavy development outside of the master codebase, but the main feature set for 1.0 was released to allow organizations to go forward with implementations that were waiting on an official release.
</p>
<h3>Documentation</h3>
<p>
We have heard you, and we are going to start improving the documentation. We&#8217;ve set up a site specific to each project (<a href="http://masstransit-project.com/">MassTransit</a>, <a href="http://topshelf-project.com/">Topshelf</a>, <a href="http://magnum-project.net/">Magnum</a>) and are going to be harvesting the <a href="http://masstransit.pbworks.com/">content from the wiki</a> to create a reference set of documentation for using MassTransit. Hopefully we can take some of the questions from <a href="http://groups.google.com/group/masstransit-discuss">the discussion list</a> and get them into a QA/FAQ section as well.
</p>
<p>
<em>As an aside, I started this post based on a purse fight that was held on Twitter this morning in regards to OSS activity in the .NET community. It is certainly important as an open source project owner to keep the lines of communication flowing in regards to the project status, new features, and roadmap. I plan to work with Dru over the next few days to get these details laid out on the web site so that we can get feedback from the community.</em>
</p>
<p>
In the next few weeks, I hope to start detailing out some of the 2.0 features that are planned for MassTransit. There are several exciting features in the <em>pipeline</em>, including an entirely new set of edge components for interfacing with clients connected via Ajax/JSON, WCF, or regular web services. As I get my act<span style="color:white">ors</span> together, I hope to post some details, as well as complete my series on building a service gateway using the new edge components.</p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2010/05/04/masstransit-update/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Leveraging Windows 7 Boot to VHD to Test Visual Studio 2010</title>
		<link>http://lostechies.com/chrispatterson/2010/01/02/leveraging-windows-7-boot-to-vhd-to-test-visual-studio-2010/</link>
		<comments>http://lostechies.com/chrispatterson/2010/01/02/leveraging-windows-7-boot-to-vhd-to-test-visual-studio-2010/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 00:11:01 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">/blogs/chris_patterson/archive/2010/01/01/leveraging-windows-7-boot-to-vhd-to-test-visual-studio-2010.aspx</guid>
		<description><![CDATA[The goal of this article is simple: a clean installation of Windows 7 that can be used to test new versions of Visual Studio 2010 until we reach RTM. Since a new beta drops every couple of months (and maybe&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2010/01/02/leveraging-windows-7-boot-to-vhd-to-test-visual-studio-2010/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
The goal of this article is simple: a clean installation of Windows 7 that can be used to test new versions of Visual Studio 2010 until we reach RTM. Since a new beta drops every couple of months (and maybe even an interim release or two in between for those lucky enough to get access to it), I don&#8217;t want to have to repave the machine for each new release. Since Windows 7 has the ability to boot into a VHD, I thought this would be the perfect opportunity to try this functionality myself.
</p>
<h3>Getting Started</h3>
<p>
The first thing I did was slide the Windows 7 DVD into the drive and rebooted the machine. Once the setup window appeared, I pressed Shift+F1 to open a command prompt and created a new VHD by typing the commands shown below.
</p>
<p><tt>&lt;br /&gt;<br />
diskpart&lt;br /&gt;<br />
create vdisk file="d:vhdsw7base.vhd" type=expandable maximum=80000&lt;br /&gt;<br />
select vdisk file="d:vhdsw7base.vhd"&lt;br /&gt;<br />
attach vdisk&lt;br /&gt;<br />
</tt>
</p>
<p>
Once this was finished, I switched back to the setup window and clicked Install Now. I chose the advanced install option, after which I selected my newly created partition as the installation target and formatted it so the installation could continue. While waiting for the setup process to complete (which included at least two reboots, both of which properly loaded into the VHD without any issues, so that&#8217;s cool), I started working on this blog post.
</p>
<p>
After the install completed, I wanted to make sure I didn&#8217;t get confused by the boot manager now having two &#8220;Windows 7&#8243; options at started. So I quickly opened a command prompt (as Administrator), and typed:
</p>
<p><tt>&lt;br /&gt;<br />
bcdedit /set description "Windows 7 Baseline"&lt;br /&gt;<br />
</tt>
</p>
<p>
This will change the name of the boot manager entry for the current machine to &#8220;Windows 7 Baseline,&#8221; distinguishing it from the normal Windows 7 install. Once I&#8217;ve completed all the setup tasks, I&#8217;ll set the regular Windows 7 option to be the default when I&#8217;m not working with the beta software installations.
</p>
<p>
Next I ran Windows Update, along with installing the <a href="http://www.microsoft.com/Security_Essentials">Microsoft Security Essentials</a> to have a basic level of virus/malware protection.
</p>
<p>
I almost always need a database server to do any sort of distributed application testing, so I wanted to have a SQL Server 2008 available. However, I didn&#8217;t want to have it setup on each virtual disk. So I installed it to the base installation, along with a few other tools that I use often (and are not really updated regularly). I also decided that since Visual Studio 2010 and Visual Studio 2008 run nicely side-by-side that I would go ahead and install Visual Studio 2008 on the base image since I&#8217;ll most likely be working primarily with 2008 through the next year.
</p>
<p>
When you boot from a VHD, your regular Windows system drive is available as drive D. This is really useful since you can keep a single checkout of all your projects and work on them from different systems! On my regular Windows 7 install, I created a &#8220;Shared&#8221; folder off the root (OMG not a Library?). Within that folder I have a Home folder which I use for SVN checkouts, and I also configured SQL Server to use a directory under Shared for all the data storage. This will be handy for ensuring that data in the database is updated regardless of which system is using SQL &#8211; very cool.
</p>
<h3>Making a Difference</h3>
<p>
With the above steps behind us, we now have a machine with two Windows 7 installations on it. The first, a regular disk-based install, is our primary installation that we use for whatever. The second, a VHD-based install, is our clean Windows 7 with our minimum set of software installed on it. It&#8217;s this clean version that we want to keep &#8220;pristine&#8221; to avoid having to redo all the steps above with each new release of Visual Studio 2010.
</p>
<p>
<em>A quick note, the size of the VHD after all the software is installed is about 20 gigabytes, which is pretty substantial considering that we now don&#8217;t need to copy this space for each branch of the baseline we create &#8212; a nice savings!</em>
</p>
<p>
To create the differential image, I restarted the machine and selected my regular disk-based Windows 7 install. Once it was loaded, I opened up a command prompt and created a new VHD based off the existing one I just finished creating.
</p>
<p><tt>&lt;br /&gt;<br />
diskpart&lt;br /&gt;<br />
create vdisk file="D:vhdsw7-2008.vhd" parent="D:vhdsw7base.vhd"&lt;br /&gt;<br />
create vdisk file="D:vhdsw7-2010.vhd" parent="D:vhdsw7base.vhd"&lt;br /&gt;<br />
</tt>
</p>
<p>Once the partition is created, create a boot entry for it using:
</p>
<p><tt>&lt;br /&gt;<br />
bcdedit /v &lt;em&gt;(this displays the GUID we'll use next for our copy)&lt;/em&gt;&lt;br /&gt;<br />
bcdedit /copy {3F2504E&lt;strong&gt;0&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} /d "Windows 7 - 2008"&lt;br /&gt;<br />
bcdedit /v &lt;em&gt;(to get the GUID of our copy, which is also displayed after the copy command as well)&lt;/em&gt;&lt;br /&gt;<br />
bcdedit /set {3F2504E&lt;strong&gt;1&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} device vhd="[C:]vhdsw7-2008.vhd"&lt;br /&gt;<br />
bcdedit /set {3F2504E&lt;strong&gt;1&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} osdevice vhd="[C:]vhdsw7-2008.vhd"&lt;br /&gt;<br />
bcdedit /v &lt;em&gt;(to verify our work)&lt;/em&gt;&lt;br /&gt;<br />
bcdedit /set {3F2504E&lt;strong&gt;2&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} device vhd="[C:]vhdsw7-2010.vhd"&lt;br /&gt;<br />
bcdedit /set {3F2504E&lt;strong&gt;2&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} osdevice vhd="[C:]vhdsw7-2010.vhd"&lt;br /&gt;<br />
bcdedit /v &lt;em&gt;(again, to verify our work)&lt;/em&gt;&lt;br /&gt;<br />
bcdedit /displayorder {current} {3F2504E&lt;strong&gt;1&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301} {3F2504E&lt;strong&gt;2&lt;/strong&gt;-4F89-11D3-9A0C-0305E82C3301}&lt;br /&gt;<br />
</tt><br />
In this case, {3F2504E<strong>0</strong>-4F89-11D3-9A0C-0305E82C3301} is my original VHD-based install, {3F2504E<strong>1</strong>-4F89-11D3-9A0C-0305E82C3301} is my copy for Visual Studio 2008, and {3F2504E<strong>2</strong>-4F89-11D3-9A0C-0305E82C3301} is my copy for Visual Studio 2010.
</p>
<p>
I now have three boot options when the system starts, my disk-based Windows 7 install, and my two newly created &#8220;differential&#8221; installs &#8212; one for Visual Studio 2008 and one for Visual Studio 2010. Since both of these are based off the VHD we created above, we want to make sure we don&#8217;t accidentally boot into the w7base VHD and change it &#8212; that would be like crossing the streams in Ghostbusters (read: bad). The /displayorder command takes care of this by having a side effect of removing the Windows 7 Baseline option from the list of boot configurations.
</p>
<p>
One thing to keep in mind, and another benefit of having the physical disk drive available as drive D, is that I do all of my work on the D drive (in the Shared folder). Since this drive is persistent I can be sure that I don&#8217;t lose my files as I boot between different installations of Windows 7. It also makes it so I don&#8217;t have to checkout projects on each VHD, which would waste valuable space.
</p>
<h3>Cleaning Up</h3>
<p>
So now that we have a nice baseline and a couple of working boot options (both of which don&#8217;t impact each other as changes are made), we can install our latest BETA/CTP/whatever on our 2010 install. When an update is released (in the form of a subsequent CTP, beta, etc.), we can take a few simple steps to revert our 2010 to a clean install.
</p>
<p>
First, we need to boot into our disk-based installation of Windows 7. Once there, there are a couple of options available. We could create an entirely new configuration by repeating the steps above. This would be helpful if we were in the middle of something on a current version of 2010 and wanted to try it in the update to check for breaking changes. The more likely option, however, is to just replace the installation with a clean baseline to install fresh.
</p>
<p>
To install fresh, we can just delete the existing w7-2010.vhd and create it again using:
</p>
<p><tt>&lt;br /&gt;<br />
diskpart&lt;br /&gt;<br />
create vdisk file="D:vhdsv7-2010.vhd" parent="D:vhdsw7base.vhd"&lt;br /&gt;<br />
</tt><br />
The boot configuration is still pointing to that file, so it will find it after a restart and you can install the latest update without fear of some bad configuration/files from a previous beta/CTP getting in the way.
</p>
<h3>Conclusion</h3>
<p>
The new boot to VHD features of Windows 7 (which also work just fine for Windows 2008 Server R2 by the way) are a really slick addition to the Windows platform. Being able to take advantage of the VHD features, differential disks in particular, really makes it a great host for the various incarnations of Visual Studio. I hope this guide has helped ease some of the CTP/BETA pain that comes with running on the bleeding edge.</p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2010/01/02/leveraging-windows-7-boot-to-vhd-to-test-visual-studio-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Traveling to Technical Events</title>
		<link>http://lostechies.com/chrispatterson/2009/12/23/traveling-to-technical-events/</link>
		<comments>http://lostechies.com/chrispatterson/2009/12/23/traveling-to-technical-events/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 16:49:20 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">/blogs/chris_patterson/archive/2009/12/23/traveling-to-technical-events.aspx</guid>
		<description><![CDATA[Over the past couple of years I have been traveling more, both for work and to attend and/or present at a variety of technical events. While I have yet to earn the esteemed grizzled road veteran merit badge, I have&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2009/12/23/traveling-to-technical-events/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over the past couple of years I have been traveling more, both for work and to attend and/or present at a variety of technical events. While I have yet to earn the esteemed grizzled road veteran merit badge, I have managed to learn a few things along the way. When presenting at a technical event, whether it is a user group meeting, a code camp, or a full blown conference, being prepared is critical to delivering a successful presentation (hey, you aren&rsquo;t paying for this advice, so don&rsquo;t expect it to be groundbreaking).</p>
<p>In this post, I would like to share with you a few things that I have found that can make the difference between a good event and a great event, at least as far as your presentation is concerned.</p>
<h3>Before You Leave (a.k.a. Pack Lightly, But Carry An Armored Tank Division)</h3>
<p>If you pack a multiple outlet power strip, you will make friends. Power outlets are like gold at any technical event and people will covet them to charge up their power hungry devices. If you encounter a full tap and plan to stay for more than a few minutes, pull it out and share the juice with your five new friends. I have a very compact one that turns 2 outlets into 6, as well as a slightly larger unit that provides 3-to-1 expansion along with 2 USB ports for charging iPhone, iPod, or other USB-powered devices.</p>
<p>If you will be driving during any part of the trip, pack a car charger for your devices. Small and compact usually wins, so I prefer something that gives me at least two USB connections from the 12V plug. That is usually enough to charge my phone and headset, and can help charge a friends phone at the same time (since they likely forgot their charger unless you forwarded them a link to this article).</p>
<p>Don&rsquo;t forget to bring plenty of cables. I always pack at least one 14-foot network cable, two USB-to-mini-USB cables, one USB-to-micro-USB cable, one firewire 800 cable, and a 800/400 adapter. The power supply for your laptop is pretty important too, so bring that long as well.</p>
<p>Bring an additional mobile phone battery or a battery powered top-up charger to get you through the trip. Nothing drains an iPhone like watching a movie during the flight, firing up the GPS to find your way to the hotel, checking your email and flight status, etc. I bought an inexpensive unit from Monoprice (less than $20) that connects to the bottom and tops off an iPhone that is under 20%. It has another dock connector on the bottom and charges from the same cable as the iPhone.</p>
<p>Scope out your network availability and plan accordingly. If you are traveling alone and cannot tether your phone to your laptop, make sure wireless networking is available. If it is not available, be sure to have all the software you need installed and make sure your demo doesn&rsquo;t require an internet connection. If you are traveling with others and the hotel charges for internet, considering bringing along a wireless router (the Airport Express from Apple is small and easy to setup) to share the connection with your friends!</p>
<p>A quick note about travel gear &#8211; carry on only. Do not check a bag, it will only slow you down. If last minute flight changes are needed when travel issues occur, being quick and unencumbered by checked baggage will help you out. Also, the 22&rdquo; roller bags will not fit in smaller aircraft, so get yourself a smaller 17&rdquo; one that fits under the seat (and in the overhead on the smaller regional jets). You can easily make a two day trip with a smaller bag, particularly if you avoid different styles of clothes.</p>
<h3>En Route (cue Vacation theme music)</h3>
<p>First things first &mdash; if you don&rsquo;t have an iPhone (or some other type of reliable smartphone), get one. I have found that having an always available internet connection, full web browser, instant email access, real-time flight tracking, and live Google maps with GPS to be the most important tools when traveling. </p>
<p>Now that you have your iPhone, some great apps that will really help your trip are listed below.</p>
<ul>
<li>AutoPilot from USA TODAY is a great, free application for managing your travel. It&rsquo;s not the fastest or best, but it is free and includes TripIt integration for loading your flight information.</li>
<li>Flight Update Pro is a air travel focused app that is highly accurate in keeping you up-to-date on flight status and arrival/departure times. While expensive ($9.99), it also includes TripIt integration (saving you data entry) and an easy to read status. </li>
<li>The FlightCaster web is fairly accurate at predicting delays, and they also have an iPhone application. Again, integration with TripIt eliminates the duplicate entry of information.</li>
</ul>
<p>By the way, if you aren&rsquo;t using TripIt to consolidate all of your booking confirmations into a single site yet &mdash; do it. TripIt can parse the details from most booking confirmation emails and automatically updates your travel calendar (which you can subscribe to using iCal). I setup a filter in Gmail to forward my confirmation emails to plans@tripit.com, which parses the message and updates your travel calendar.</p>
<p>And hopefully this goes without saying, but when traveling &mdash; particularly by air &mdash; dress respectable, be courteous, and don&rsquo;t lose your temper. Things happen during travel &mdash; delayed flights, road construction, missed exits, engine fires &mdash; most of these are out of your control. The last thing you want to do is be an ass to a person already under pressure. Being polite can mean the difference between getting the last seat on the last flight and sleeping on the airport floor. Oh, and when at all possible, use your phone since there are more agents at the call center who can help get you on the right flight then there are at the airport helping the people in line.</p>
<h3>After Arriving (the night before)</h3>
<p>Do not let any friends, co-workers, acquaintances, or otherwise get you drunk because presenting with a hangover is just not cool. And that&rsquo;s all I&rsquo;ve got to say about that.</p>
<h3>Presenting (drum roll, please)</h3>
<p>If you are presenting to a Microsoft-centric audience and you are using a Mac, make sure you have everything you need to peacefully coexist in a Windows world. You will get the inevitable comments about running a Mac, so the last thing you want is to fail due to hardware or software issue. To help you out, here are a few tips:</p>
<p>Almost every projector you come across will use an analog VGA (d-sub) connector, so be sure to keep a Mini DisplayPort to VGA (or DVI to VGA for older Macs) in your backpack. It doesn&rsquo;t hurt to have a Mini DisplayPort to DVI as well in case you encounter a more modern project (although I&rsquo;ve seen more HDMI than DVI projectors this past year &mdash; all of which also supported VGA). I also pack actual video cables as well in case you end up doing an ad-hoc session in your hotel room.</p>
<p>Many groups like to record or broadcast their sessions so that members unable to participate in person can view the presentation. To make things easy, be sure to have LiveMeeting already setup and tested on your machine. If you are on a Mac, this means converting your presentation from Keynote to either PowerPoint (using the free PowerPoint viewer if necessary) or Quicktime and presenting the slides from Windows. If you are not doing any Windows-based demos (like if you were giving an iPhone development talk), well, the remote folks are out of luck!</p>
<p>If your talk is less about code and more about practices or principles, use the presenter display from Keynote or Powerpoint on your laptop. This helps you keep track of time, review your slide notes, and preview the next slide (which helps you avoid talking ahead of your deck). On the other hand, with code focused sessions stick to a mirrored display in the native resolution of the projector.</p>
<p>When presenting code it is best to use a white background with black text. While the dark themes are great for large screen monitors, they look terrible on projectors with monospaced fonts. Many editors allow you to save and load settings, so build yourself a presentation mode settings file. With a set of high contrast colors (the default Visual Studio colors are a bit too hard to read at 25 feet) and a font size of 12-14 you&rsquo;ll be all set to show your code to a large room. Font choice is another thing. While Consolas is my favorite, at larger font sizes it looks terrible &#8211; particularly in bold. Consider an alternate font for your presentation settings that looks good at a large font size.</p>
<p>When presenting with slides, a remote is a great way to get out from behind the podium. I like to present while standing in front of the screen, so I always pack my Apple remote. I tend to avoid the higher tech solutions such as the Keynote Remote app for the iPhone as they tend to just get in the way. If you need to use the remote to control PowerPoint, there are some utilities that will make that work as well.</p>
<h3>Choose Your Own Adventure (n, n, open door, n, e, melt wizard)</h3>
<p>Most of the time, your presentation is going to be perfect for the audience. Assuming that your session description was accurate and a level of learning was indicated you should be set. However, your audience might not be prepared for the material being covered. In these situations it is best to have an alternative path that your presentation can take, one that is more appropriate for a general audience. In some cases this might not be possible, but it can really make the difference between an engaged audience and a bunch of people cleaning out their inbox (because there is likely was too much caffeine in their blood to actually sleep).</p>
<h3>Wrap It Up (I&rsquo;ll take it)</h3>
<p>I hope the tips I&rsquo;ve shared with you here will be useful if you decide to step up to the podium. There are many other posts that talk about slide design, demo subject matter, travel tips, and more but the items above are some of the ones I&rsquo;ve had to learn on my own (and thankfully not always the hard way &mdash; well except for one).</p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2009/12/23/traveling-to-technical-events/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building a Service Gateway Using MassTransit, Part 3</title>
		<link>http://lostechies.com/chrispatterson/2009/11/01/building-a-service-gateway-using-masstransit-part-3/</link>
		<comments>http://lostechies.com/chrispatterson/2009/11/01/building-a-service-gateway-using-masstransit-part-3/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 02:58:25 +0000</pubDate>
		<dc:creator>Chris Patterson</dc:creator>
				<category><![CDATA[masstransit]]></category>

		<guid isPermaLink="false">/blogs/chris_patterson/archive/2009/10/31/building-a-service-gateway-using-masstransit-part-3.aspx</guid>
		<description><![CDATA[This post is the third in a series on building a highly available service gateway. The implementation will be built in C# using MassTransit, StructureMap, ASP.NET MVC, and NHibernate. Did somebody say code? The past two posts began to explain&#160;&#8230; <a href="http://lostechies.com/chrispatterson/2009/11/01/building-a-service-gateway-using-masstransit-part-3/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>This post is the third in a series on building a highly available service gateway. The implementation will be built in C# using <a href="http://code.google.com/p/masstransit/">MassTransit</a>, <a href="http://structuremap.sourceforge.net/Default.htm">StructureMap</a>, <a href="http://www.asp.net/mvc/">ASP.NET MVC</a>, and <a href="http://nhforge.org/">NHibernate</a>.</em>
</p>
<h3>Did somebody say code?</h3>
<p>
The past two posts began to explain how to build a service gateway using MassTransit. In this post, I&#8217;m going to share some of the initial code that makes up the gateway service. The gateway itself consists of two components. The first implements the communication to the external service with a set of messages that are only used internally by the service. The second is the saga that provides the interface to the service gateway.
</p>
<h3>Service Contract</h3>
<p>The interface exposed to the application consists of two messages, the first for the command and the second for the response. The message contracts are defined using interfaces, allowing the class for the message to be an internal implementation detail.
</p>
<p>
The message contract representing a request for order details includes the CustomerId and the OrderId.
</p>
<pre>
public interface RetrieveOrderDetails
{
	string OrderId { get; }
	string CustomerId { get; }
}
</pre>
<p>
When the order details are received, the following message is published.
</p>
<pre>
public interface OrderDetailsReceived
{
	string OrderId { get; }
	string CustomerId { get; }
	DateTime Created { get; }
	OrderStatus Status { get; }
}

public enum OrderStatus
{
	Unknown = 0,
	Submitted = 1,
	Accepted = 2,
	InProcess = 3,
	Complete = 4,
}
</pre>
<p>
The CustomerId and OrderId are the same as the values passed in the request. Created is when the order was created, and Status is an enum representing the status of the order. Notice that no internal values are included &#8212; no primary key from the order table and no primary key from the customer table. The request and response are correlated on identifiers that make sense in the application domain. While SQL purists will point out that numeric primary keys are quicker for retrieving rows in a database, they make for a very fragile interface with other components in the system. Reliance on a primary key outside of the context of the system storing the order details is a path to friction or outright failure.
</p>
<h3>Time To Make the Saga</h3>
<p>
At this point in the design of our service, the need for a saga to manage the request state is not entirely obvious. While the TDD purists might want to call YAGNI at this point, let me assure you that &#8220;it will all be&#8230; revealed!&#8221; So for now, let us take a look at the first pass of our saga definition.
</p>
<pre>
public class OrderDetailsRequestSaga :
	SagaStateMachine&lt;OrderDetailsRequestSaga&gt;,
	ISaga
{
	static OrderDetailsRequestSaga()
	{
		Define(Saga);
	}
</pre>
<p>
Our saga state machine uses a static initializer to define the states, events, and transitions of a saga. The previous code merely defines our class as a saga and calls our saga initialization method (shown below).
</p>
<pre>
	private static void Saga()
	{
		Correlate(RequestReceived)
			.By((saga, message) =&gt; saga.CustomerId == message.CustomerId &amp;&amp;
			                       saga.OrderId == message.OrderId &amp;&amp;
			                       saga.CurrentState == WaitingForResponse);

		Correlate(ResponseReceived)
			.By((saga, message) =&gt; saga.CustomerId == message.CustomerId &amp;&amp;
			                       saga.OrderId == message.OrderId &amp;&amp;
			                       saga.CurrentState == WaitingForResponse);
</pre>
<p>
Since our request criteria include our customer id and our order id, we use those to correlate the message to the saga. We also include the state of the saga to ensure that we do not match to a request that has already completed. We will look at some other ways we can enhance the performance of the service later on by using some additional states.
</p>
<pre>
	public static State Initial { get; set; }
	public static State WaitingForResponse { get; set; }
	public static State Completed { get; set; }
</pre>
<p>
The three states we have defined, including an initial state when a new saga instance is created, a waiting for response state one our request has been sent to the service, and a completed state once the response has been received and published.
</p>
<pre>
	public static Event&lt;RetrieveOrderDetails&gt; RequestReceived { get; set; }
	public static Event&lt;OrderDetailsResponse&gt; ResponseReceived { get; set; }
	public static Event&lt;OrderDetailsRequestFailed&gt; RequestFailed { get; set; }
</pre>
<p>
The three events that we have defined, including the message contract that maps to the event. The subscription logic for the saga will automatically map message handlers for these events that will invoke the actions depending upon the current state of the saga.
</p>
<pre>
		Initially(
			When(RequestReceived)
				.Then((saga, request) =&gt;
					{
						saga.OrderId = request.OrderId;
						saga.CustomerId = request.CustomerId;
					})
				.Publish((saga, request) =&gt; new SendOrderDetailsRequest
					{
						RequestId = saga.CorrelationId,
						CustomerId = saga.CustomerId,
						OrderId = saga.OrderId,
					})
				.TransitionTo(WaitingForResponse));
</pre>
<p>
The first event handler, RequestReceived, is invoked when the saga is created in response to the RetrieveOrderDetails message. The handler copies the properties of the request, and then publishes the request message to the proxy that will call the external web service. After the message is published, the state of the saga transitions to the waiting for response state. When using transactional queues, the receipt of the message, creation of the saga in the database, sending of the command message to the proxy, and saving the saga are all part of a single distributed transaction. This ensures that everything completes as a single operation to ensure no requests are lost.
</p>
<pre>
		During(WaitingForResponse,
			When(ResponseReceived)
				.Then((saga, response) =&gt;
					{
						saga.OrderCreated = response.Created;
						saga.OrderStatus = response.Status;
					})
				.Publish((saga, request) =&gt; new OrderDetails
					{
						CustomerId = saga.CustomerId,
						OrderId = saga.OrderId,
						Created = saga.OrderCreated.Value,
						Status = saga.OrderStatus,
					})
				.TransitionTo(Completed));
	}
</pre>
<p>
The second event handler, ResponseReceived, is invoked when the OrderDetailsResponse message is received. The results of the request are stored in the saga and a message is published containing the details of the order back to the original requestor. Another approach would be to capture the requestor address (via the ResponseAddress header from the message) and then resolve that address using the endpoint factory to send the response directly to the requestor. I don&#8217;t really encourage this approach without having a truly unique identifier for each request.
</p>
<pre>
	public OrderDetailsRequestSaga(Guid correlationId)
	{
		CorrelationId = correlationId;
	}

	protected OrderDetailsRequestSaga()
	{
	}

	public virtual string CustomerId { get; set; }
	public virtual string OrderId { get; set; }
	public virtual OrderStatus OrderStatus { get; set; }
	public virtual DateTime? OrderCreated { get; set; }

	public virtual Guid CorrelationId { get; set; }
	public virtual IServiceBus Bus { get; set; }
}
</pre>
<p>
The rest of the saga class is shown above for completeness. The properties are part of the saga and get saved when the saga is persisted (using the NHibernate saga persister, or in the case of the sample the in-memory implementation). The constructor with the Guid is used to initialize the saga when a new one is created, the protected one is there for NHibernate to be able to persist the saga.
</p>
<h3>The Service Proxy</h3>
<p>
The saga uses the external service proxy to perform the actual work, which is shown in the proxy class below.
</p>
<pre>
public class OrderDetailsWebServiceProxy :
	Consumes&lt;SendOrderDetailsRequest&gt;.All
{
	public void Consume(SendOrderDetailsRequest request)
	{
		// make the call to the service to get the order details here

		var details = new OrderDetailsResponse
			{
				OrderId = request.OrderId,
				CustomerId = request.CustomerId,
				Created = (-1).Days().FromUtcNow(),
				Status = OrderStatus.InProcess,
			};

		CurrentMessage.Respond(details, x =&gt; x.ExpiresAt(5.Minutes().FromNow()));
	}
}
</pre>
<p>
The message handler uses the criteria from the SendOrderDetailsRequest message (which was published by the saga) to call the external service and retrieve the order details. The details are then returned to the saga in the form of an OrderDetailsResponse message which is internal to the service (and therefore not part of the interface assembly that is provided to applications that want to use the order details service).
</p>
<h3>Test That Thang</h3>
<p>
Now that our saga has been developed, we need to be able to test it. A unit test will be created that creates a testing instance of the service bus (see the sample for the implementation details) and verifies that the saga responds properly to the request. To request order details, a very simple client would subscribe to the response message and then publish the request.
</p>
<pre>
const string orderId = "ABC123";
const string customerId = "12345";

LocalBus.Subscribe&amp;lt; OrderDetailsReceived &gt;(message =&gt;
	{
		response.Set(message);
	},
	x =&gt; x.OrderId == orderId &amp;&amp; x.CustomerId == customerId);

RetrieveOrderDetails request = new RetrieveOrderDetailsRequest(customerId, orderId);
LocalBus.Publish(request, x =&gt; x.SendResponseTo(LocalBus.Endpoint));
</pre>
<p>
The subscribe method used above specifies that when a message of type OrderDetailsReceived is received, if the contents of the message match the predicate specified (which in this case, is checking the OrderId and CustomerId contained in the message) then the statement specified should be called. Our example is from the integration test (built using NUnit) that verifies the service performs from end-to-end.
</p>
<p>
The syntax above is functional, and it will work, but it does not represent the most scalable approach. In the next post, I&#8217;ll start to explain how to build a much more scalable method of handling thousands of concurrent requests on a single machine using IIS.
</p>
<p>
In the meantime, the sample code is available in the MassTransit trunk as a standalone solution. You can find it in the trunksrcSamplesServiceGatewaySample folder. There are unit tests that verify the calling syntax shown above and a service that hosts the services (both the saga, and the proxy service).</p>
]]></content:encoded>
			<wfw:commentRss>http://lostechies.com/chrispatterson/2009/11/01/building-a-service-gateway-using-masstransit-part-3/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

