﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com/blog/</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2012 (c) 2012</copyright><ttl>60</ttl><item><title>And this is Ironic</title><description>&lt;p&gt;I was trying to press the Yes button, and this happened:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/And-this-is-I_C621/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/And-this-is-I_C621/image_thumb.png" width="1524" height="248"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To be fair, I am trying to get it to read my mail, and it is a bit… largish, I guess:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/And-this-is-I_C621/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/And-this-is-I_C621/image_thumb_2.png" width="341" height="22"&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ayende.com/blog/155777/and-this-is-ironic?key=0421a4fc-ed9c-4ec3-b17b-e5d679e62cee</link><guid>http://ayende.com/blog/155777/and-this-is-ironic?key=0421a4fc-ed9c-4ec3-b17b-e5d679e62cee</guid><pubDate>Fri, 25 May 2012 09:00:00 GMT</pubDate></item><item><title>I think that I&amp;rsquo;ll ignore this test failure</title><description>&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/I-think-that-Ill-ignore-this-test-failur_14830/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/I-think-that-Ill-ignore-this-test-failur_14830/image_thumb.png" width="829" height="191"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This really sucks, because of this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/I-think-that-Ill-ignore-this-test-failur_14830/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/I-think-that-Ill-ignore-this-test-failur_14830/image_thumb_1.png" width="550" height="67"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is part of the RavenDB release process, where we are actually hammering RavenDB and seeing if it breaks. And it usually takes about 24 hours to do a complete run.&lt;/p&gt;</description><link>http://ayende.com/blog/155745/i-think-that-irsquo-ll-ignore-this-test-failure?key=4bad89ac-f047-4047-8b8a-ba5d062e7bf7</link><guid>http://ayende.com/blog/155745/i-think-that-irsquo-ll-ignore-this-test-failure?key=4bad89ac-f047-4047-8b8a-ba5d062e7bf7</guid><pubDate>Thu, 24 May 2012 09:00:00 GMT</pubDate></item><item><title>The RavenDB Release Process</title><description>&lt;p&gt;We got several questions about this in the mailing list, so I thought that this would be a good time to discuss this in the blog. &lt;/p&gt; &lt;p&gt;One of the best part about RavenDB is that we are able to deliver quickly and continuously.&amp;nbsp; That means that we can deliver changes to the users very rapidly, often resulting in response times of less than an hour from “I have an issue” to “it is already fixed and you can download it”.&lt;/p&gt; &lt;p&gt;That is awesome on a lot of level, but it lack something very important, stability. In other words, by pushing things so rapidly, we are living on the bleeding edge. Which is great, except that you tend to bleed.&lt;/p&gt; &lt;p&gt;That is why we split the RavenDB release process into Unstable and Stable. Unstable builds are released on a “several times a day” basis, and only require that we will pass our internal test suite. This test suite is hefty, over 1,500 tests so far, but it is something that can be run in about 15 minutes or so on the developer machine to make sure that our changes didn’t break anything.&lt;/p&gt; &lt;p&gt;The release process for Stable version is much more involved. First, of course, we run the standard suite of tests. Then we have a separate set of tests, which are stress testing RavenDB by trying to see if there are any concurrency issues.&lt;/p&gt; &lt;p&gt;Next, we take the current bits and push them to our own internal production systems. For example, at the time of this writing, this blog (and all of our assets) are currently running on RavenDB build 726 and have been running that way for a few days. This allows us to test several things. That there are no breaking changes, that this build can survive running in production over extended period of time and that the overall performance remains excellent.&lt;/p&gt; &lt;p&gt;Finally, we ask users to take those builds for a spin, and they are usually far more rough on RavenDB than we are.&lt;/p&gt; &lt;p&gt;After all of that, we move to a set of performance tests, comparing the system behavior on a wide range of operations compared to the old version. &lt;/p&gt; &lt;p&gt;And then… we can do a stable release push. Phew!&lt;/p&gt;</description><link>http://ayende.com/blog/155713/the-ravendb-release-process?key=3694bc25-c5e5-45ab-93d8-d6f146ac86ac</link><guid>http://ayende.com/blog/155713/the-ravendb-release-process?key=3694bc25-c5e5-45ab-93d8-d6f146ac86ac</guid><pubDate>Wed, 23 May 2012 09:00:00 GMT</pubDate></item><item><title>RavenHQ goes out of beta</title><description>&lt;p&gt;&lt;img src="https://ravenhq.com/Content/css/images/logo.png"&gt;&lt;/p&gt; &lt;p&gt;After several months in public beta, I am proud to announce that &lt;a href="https://ravenhq.com/"&gt;RavenHQ&lt;/a&gt;, the RavenDB as a Service&amp;nbsp; on the cloud has dropped the beta label and is now ready for full production use.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;That means that we now accept signups from the general public, you no longer need an AppHarbor account and you can use it directly. It also means that you can safely start using RavenHQ for production purposes.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;RavenHQ is a fully-managed cloud of RavenDB servers and scalable plans, you’ll never have to worry about installation, updates, availability, performance, security or backups again.  &lt;p&gt;We offer both standard and high availability plans, and are the perfect fit for RavenDB users who can safely outsource all the operational support of your databases in the RavenHQ’s team capable hands.&lt;/p&gt;</description><link>http://ayende.com/blog/156289/ravenhq-goes-out-of-beta?key=25d64f6e-be22-419e-8aae-c2a9f670f81e</link><guid>http://ayende.com/blog/156289/ravenhq-goes-out-of-beta?key=25d64f6e-be22-419e-8aae-c2a9f670f81e</guid><pubDate>Tue, 22 May 2012 07:00:00 GMT</pubDate></item><item><title>If you put tripwires in my paths, you won&amp;rsquo;t get my money</title><description>&lt;p&gt;Recently I updated several of my VS plugins, and immediately after that I noticed a changed in the way VS behaves.&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/If-you-put-tripwires-in-my-paths-you-won_CC03/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/If-you-put-tripwires-in-my-paths-you-won_CC03/image_thumb.png" width="660" height="428"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is actually quite nice, and useful. (Although I was a bit confused for a time about when it shows and when it doesn’t, but that is beside the point).&lt;/p&gt; &lt;p&gt;the problem is that in many cases, like the first two example, it is actually quite easy to press on those notifications. And if you do that, you get:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/If-you-put-tripwires-in-my-paths-you-won_CC03/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/If-you-put-tripwires-in-my-paths-you-won_CC03/image_thumb_1.png" width="469" height="306"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And that is &lt;em&gt;annoying&lt;/em&gt;. Sure, I get that you want to encourage people to buy your products, I even agree. But this sort of a feature is something that is &lt;em&gt;very &lt;/em&gt;easy to invoke by mistake, and it completely throws you out of your current context. &lt;/p&gt; &lt;p&gt;I have VSCommands installed for the simple reason that I really like the Reload All feature. But it isn’t worth it if I have to be careful where I put my mouse in VS.&lt;/p&gt; &lt;p&gt;This single feature is the reason that I uninstalled it.&lt;/p&gt;</description><link>http://ayende.com/blog/154657/if-you-put-tripwires-in-my-paths-you-wonrsquo-t-get-my-money?key=e0d422db-8bf5-4ca3-a059-41a7be2259d7</link><guid>http://ayende.com/blog/154657/if-you-put-tripwires-in-my-paths-you-wonrsquo-t-get-my-money?key=e0d422db-8bf5-4ca3-a059-41a7be2259d7</guid><pubDate>Mon, 21 May 2012 09:00:00 GMT</pubDate></item><item><title>A bad test</title><description>&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/A-bad-test_14ECA/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/A-bad-test_14ECA/image_thumb.png" width="953" height="327"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is a bad test, because what it does is ensuring that something &lt;em&gt;does not works&lt;/em&gt;. I just finished implementing the session.Advaned.Defer support, and this test got my attention by failing the build.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Bad &lt;/em&gt;test, you should be telling me when I broke something, not when I added new functionality.&lt;/p&gt;</description><link>http://ayende.com/blog/155617/a-bad-test?key=681dcdab-232a-40a7-bb7a-50def0640d9b</link><guid>http://ayende.com/blog/155617/a-bad-test?key=681dcdab-232a-40a7-bb7a-50def0640d9b</guid><pubDate>Fri, 18 May 2012 09:00:00 GMT</pubDate></item><item><title>When using the Task Parallel Library, Wait() is a BAD warning sign</title><description>&lt;p&gt;Take a look at the following code:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Task ParseAsync(IPartialDataAccess source, IPartialDataAccess seed, Stream output, IEnumerable&amp;lt;RdcNeed&amp;gt; needList)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Task.Factory.StartNew(() =&amp;gt;
    {
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; needList)
        {
            &lt;span class="kwrd"&gt;switch&lt;/span&gt; (item.BlockType)
            {
                &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Source:
                    source.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength)).Wait();
                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Seed:
                    seed.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength)).Wait();
                    &lt;span class="kwrd"&gt;break&lt;/span&gt;;
                &lt;span class="kwrd"&gt;default&lt;/span&gt;:
                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotSupportedException();
            }
        }
    });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Do you see the problem in here?&lt;/p&gt;
&lt;p&gt;It is a result of a code review comment about improper use of async in a project. This resulted in a lot of Task showing up in the return methods, but not in any measurable improvement in the actual codebase use of asynchronicity.&lt;/p&gt;
&lt;p&gt;The problem is that when you need to work with such things in C# 4.0, you have to do some annoying things to get the code to work properly. In particular, this method was modified to be:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Task ParseAsync(IPartialDataAccess source, IPartialDataAccess seed, Stream output, IList&amp;lt;RdcNeed&amp;gt; needList, &lt;span class="kwrd"&gt;int&lt;/span&gt; position = 0)
{
  &lt;span class="kwrd"&gt;if&lt;/span&gt;(position&amp;gt;= needList.Count)
  {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; CompletedTask();
  }
  var item = needList[position];
  Task task;
            
  &lt;span class="kwrd"&gt;switch&lt;/span&gt; (item.BlockType)
  {
        &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Source:
            task = source.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength));
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;case&lt;/span&gt; RdcNeedType.Seed:
            task = seed.CopyToAsync(output, Convert.ToInt64(item.FileOffset), Convert.ToInt64(item.BlockLength));
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
        &lt;span class="kwrd"&gt;default&lt;/span&gt;:
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; NotSupportedException();
  }

  &lt;span class="kwrd"&gt;return&lt;/span&gt; task.ContinueWith(resultTask =&amp;gt;
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (resultTask.Status == TaskStatus.Faulted)
            resultTask.Wait(); &lt;span class="rem"&gt;// throws&lt;/span&gt;
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ParseAsync(source, seed, output, needList, position + 1);
    }).Unwrap();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This code is more complex, but it is actually making proper use of the TPL. We have changed the loop into a recursive function, so we can take advantage of ContinueWith to the next iteration of the loop.&lt;/p&gt;
&lt;p&gt;And no, I can’t &lt;em&gt;wait&lt;/em&gt; to get to C# 5.0 and have proper await work.&lt;/p&gt;</description><link>http://ayende.com/blog/155585/when-using-the-task-parallel-library-wait-is-a-bad-warning-sign?key=08f9a2f5-c34a-4961-8c19-e5782bcc39a1</link><guid>http://ayende.com/blog/155585/when-using-the-task-parallel-library-wait-is-a-bad-warning-sign?key=08f9a2f5-c34a-4961-8c19-e5782bcc39a1</guid><pubDate>Thu, 17 May 2012 09:00:00 GMT</pubDate></item><item><title>Reviewing RavenDB app: ReleaseCandidateTracker</title><description>&lt;p&gt;&lt;a href="https://github.com/SzymonPobiega/ReleaseCandidateTracker"&gt;ReleaseCandidateTracker&lt;/a&gt; is a new RavenDB based application by Szymon Pobiega. I reviewed version 5f7e42e0fb1dea70e53bace63f3e18d95d2a62dd. At this point, I don’t know anything about this application, including what exactly it means, Release Tracking.&lt;/p&gt; &lt;p&gt;I downloaded the code and started VS, there is one project in the solution, which is already a Good Thing. I decided to randomize my review approach and go and check the Models directory first. &lt;/p&gt; &lt;p&gt;Here is how it looks:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_1.png" width="983" height="671"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This is interesting for several reasons. First, it looks like it is meant to keep a record of all deployments to multiple environments, and that you can lookup the history of each deployment both on the environment side and on the release candidate side.&lt;/p&gt; &lt;p&gt;Note that we use rich models, which have collections in them. In fact, take a look at this method:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_2.png" width="1081" height="349"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Which calls to this method:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_3.png" width="602" height="243"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You know what the &lt;em&gt;really&lt;/em&gt; fun part about this? &lt;/p&gt; &lt;p&gt;It ain’t relational model. There is &lt;em&gt;no cost &lt;/em&gt;of actually making all of these calls!&lt;/p&gt; &lt;p&gt;Next, we move to the Infrastructure folder, where we have a couple of action results and the RavenDB management stuff. Here it how RCT uses RavenDB:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Database
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore storeInstance;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IDocumentStore Instance
    {
        get
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (storeInstance == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="str"&gt;"Document store has not been initialized."&lt;/span&gt;);
            }
            &lt;span class="kwrd"&gt;return&lt;/span&gt; storeInstance;
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()
    {
        var embeddableDocumentStore = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmbeddableDocumentStore {DataDirectory = &lt;span class="str"&gt;@"~\App_Data\Database"&lt;/span&gt;};
        embeddableDocumentStore.Initialize();
        storeInstance = embeddableDocumentStore;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is using an embedded database to do that, which makes it very easy to use the app. Just hit F5 and go. In fact, if we do, we see the fully functional website, which is quite awesome &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/wlEmoticon-smile_2.png"&gt;.&lt;/p&gt;
&lt;p&gt;Let us move to seeing how we are managing the sessions:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; BaseController : Controller
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IDocumentSession DocumentSession { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; CandidateService CandidateService { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; ScriptService ScriptService { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuting(ActionExecutingContext filterContext)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.IsChildAction)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        }
        DocumentSession = Database.Instance.OpenSession();
        CandidateService = &lt;span class="kwrd"&gt;new&lt;/span&gt; CandidateService(DocumentSession);
        ScriptService = &lt;span class="kwrd"&gt;new&lt;/span&gt; ScriptService(DocumentSession);
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuting(filterContext);
    }
    
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.IsChildAction)
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        }
        &lt;span class="kwrd"&gt;if&lt;/span&gt;(DocumentSession != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (filterContext.Exception == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                DocumentSession.SaveChanges();
            }
            DocumentSession.Dispose();
        }
        &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnActionExecuted(filterContext);
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is all handled inside the base controller, and it is very similar to how I am doing that in my own apps.&lt;/p&gt;
&lt;p&gt;However, ScriptService and CandidateService seems strange, let us explore them a bit.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ScriptService
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; IDocumentSession documentSession;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; ScriptService(IDocumentSession documentSession)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.documentSession = documentSession;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AttachScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, Stream fileContents)
    {
        var metadata = &lt;span class="kwrd"&gt;new&lt;/span&gt; RavenJObject();
        documentSession.Advanced.DatabaseCommands.PutAttachment(versionNumber, &lt;span class="kwrd"&gt;null&lt;/span&gt;, fileContents, metadata);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; Stream GetScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
    {
        var attachment = documentSession.Advanced.DatabaseCommands.GetAttachment(versionNumber);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; attachment != &lt;span class="kwrd"&gt;null&lt;/span&gt; 
            ? attachment.Data() 
            : &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;So this is using RavenDB attachment to store stuff, I am not quite sure what yet, so let us track it down.&lt;/p&gt;
&lt;p&gt;This is being used like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpGet]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult GetScript(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
{
    var candidate = CandidateService.FindOneByVersionNumber(versionNumber);
    var attachment = ScriptService.GetScript(versionNumber);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (attachment != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        var result = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStreamResult(attachment, &lt;span class="str"&gt;"text/plain"&lt;/span&gt;);
        var version = candidate.VersionNumber;
        var product = candidate.ProductName;
        result.FileDownloadName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"deploy-{0}-{1}.ps1"&lt;/span&gt;, product, version);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpNotFoundResult(&lt;span class="str"&gt;"Deployment script missing."&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I am assuming that the scripts are deployment scripts for different versions, and that they get uploaded on every new release candidate.&lt;/p&gt;
&lt;p&gt;But look at the CandidateService, it looks like a traditional service wrapping RavenDB, and I have spoken against it multiple times.&lt;/p&gt;
&lt;p&gt;In particular, I dislike this bit of code:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ReleaseCandidate FindOneByVersionNumber(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber)
{
    var result = documentSession.Query&amp;lt;ReleaseCandidate&amp;gt;()
        .Where(x =&amp;gt; x.VersionNumber == versionNumber)
        .FirstOrDefault();
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(result == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateNotFoundException(versionNumber);
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Store(ReleaseCandidate candidate)
{
    var existing = documentSession.Query&amp;lt;ReleaseCandidate&amp;gt;()
        .Where(x =&amp;gt; x.VersionNumber == candidate.VersionNumber)
        .Any();
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (existing)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateAlreadyExistsException(candidate.VersionNumber);
    }
    documentSession.Store(candidate);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;From looking at the code, it looks like the version number of the release candidate is the primary way to look it up. More than that, in the entire codebase, there is never a case where we load a document by id.&lt;/p&gt;
&lt;p&gt;When I see a VersionNumber, I think about things like “1.0.812.0”, but I think that in this case the version number is likely to include the product name as well, “RavenDB-1.0.812.0”, otherwise you couldn’t have two products with the same version.&lt;/p&gt;
&lt;p&gt;That said, the code above it wrong, because it doesn’t take into account RavenDB’s indexes BASE nature. Instead, the version number should actually be the ReleaseCandidate id. This way, because RavenDB’s document store is fully ACID, we don’t have to worry about index update times, and we can load things very efficiently.&lt;/p&gt;
&lt;p&gt;Pretty much all of the rest of the code in the CandidateService is only used in a single location, and I don’t really see a value in it being there.&lt;/p&gt;
&lt;p&gt;For example, let us look at this one:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpPost]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult MarkAsDeployed(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, &lt;span class="kwrd"&gt;string&lt;/span&gt; environment, &lt;span class="kwrd"&gt;bool&lt;/span&gt; success)
{
    CandidateService.MarkAsDeployed(versionNumber, environment, success);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; EmptyResult();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-RavenDB-app-ReleaseCandidateTr_A3DC/image_thumb_4.png" width="600" height="729"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, it is merely loading the appropriate release candidate, and calling the MarkAsDeployed method on it.&lt;/p&gt;
&lt;p&gt;Instead of doing this needless, forwarding, and assuming that we have the VersionNumber as the id, I would write:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpPost]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult MarkAsDeployed(&lt;span class="kwrd"&gt;string&lt;/span&gt; versionNumber, &lt;span class="kwrd"&gt;string&lt;/span&gt; environment, &lt;span class="kwrd"&gt;bool&lt;/span&gt; success)
{
    var cadnidate = DocumentSession.Load&amp;lt;ReleaseCandidate&amp;gt;(versionNumber);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (cadnidate == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReleaseCandidateNotFoundException(versionNumber);
    var env = DocumentSession.Load&amp;lt;DeploymentEnvironment&amp;gt;(environment);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (env == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"Environment {0} not found"&lt;/span&gt;, environment));

    cadnidate.MarkAsDeployed(success, env);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; EmptyResult();
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Finally, a word about the error handling, this is handled via:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnException(ExceptionContext filterContext)
{
    filterContext.Result = &lt;span class="kwrd"&gt;new&lt;/span&gt; ErrorResult(filterContext.Exception.Message);
    filterContext.ExceptionHandled = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ErrorResult : ActionResult
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;readonly&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; message;

    &lt;span class="kwrd"&gt;public&lt;/span&gt; ErrorResult(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.message = message;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.Write(message);
        context.HttpContext.Response.StatusCode = 500;
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;The crazy part is that OnException is overridden only on some of the controllers, rather than in the base controller, and even worse. This sort of code leads to error details loss.&lt;/p&gt;
&lt;p&gt;For example, let us say that I get a NullReferenceException. This code will dutifully tell me all about it, &lt;em&gt;but will not tell me where it happened&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This sort of thing make debugging &lt;em&gt;extremely&lt;/em&gt; hard.&lt;/p&gt;</description><link>http://ayende.com/blog/155553/reviewing-ravendb-app-releasecandidatetracker?key=ebf8a35d-96b1-419c-be31-518497decac2</link><guid>http://ayende.com/blog/155553/reviewing-ravendb-app-releasecandidatetracker?key=ebf8a35d-96b1-419c-be31-518497decac2</guid><pubDate>Wed, 16 May 2012 09:00:00 GMT</pubDate></item><item><title>Non overlapping time periods&amp;ndash;because I like the pain of 2 AM wakeup calls</title><description>&lt;p&gt;
	This post is partly in response for &lt;a href="http://codebetter.com/johnvpetersen/2012/03/13/229-the-case-of-the-missing-data-point-and-the-curious-thing-a-leap-year-is/"&gt;this post&lt;/a&gt;, discussing the Azure problem with leap year. But it is actually a bit more general than that.&lt;/p&gt;
&lt;p&gt;
	In my code, here is how I define &amp;ldquo;one year from now&amp;rdquo;:&lt;/p&gt;
&lt;blockquote&gt;
	&lt;p&gt;
		DateTime.Today.AddYears(1).AddDays(3);&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
	As it turned out, this tend to have a lot of implications on your business, most of them are actually pretty good ones.&lt;/p&gt;
&lt;p&gt;
	For a start, you will never get hit with a leap year bug, but more importantly, you are never going to have to deal with an immediate cutoff. This is important because it gives you time. Mostly, it gives you time to screw up, but having the time to do so without having an egg all of your face is a really nice thing.&lt;/p&gt;
&lt;p&gt;
	For example, all of our subscriptions are using a similar method of calculation, and this is why we can take the ordering system down for a few hours or even a day or two and no one will actually notice. We have a big grace period in which we can work things out.&lt;/p&gt;
&lt;p&gt;
	Sure, a user gets 3 &amp;ldquo;extra&amp;rdquo; days for free out of this, but frankly, I don&amp;rsquo;t give a damn. It is more important that I get the buffer, and most users like it much better when you don&amp;rsquo;t slam the doors in their faces on the first chance.&lt;/p&gt;
&lt;p&gt;
	One of the things that is important is &lt;em&gt;style&lt;/em&gt;, and giving a grace period for those sort of things is crucial.&lt;/p&gt;
</description><link>http://ayende.com/blog/155521/non-overlapping-time-periodsndash-because-i-like-the-pain-of-2-am-wakeup-calls?key=d3ef0b84-4bb5-4f6a-9679-6759e89eef46</link><guid>http://ayende.com/blog/155521/non-overlapping-time-periodsndash-because-i-like-the-pain-of-2-am-wakeup-calls?key=d3ef0b84-4bb5-4f6a-9679-6759e89eef46</guid><pubDate>Tue, 15 May 2012 09:00:00 GMT</pubDate></item><item><title>Rotten Scheduling: Don&amp;rsquo;t roll your own</title><description>&lt;p&gt;“We need to run a specific task every 72 hours, I thought about this approach…”&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimedTask
{
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Timer Timer;
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Init()
  {
    Timer = &lt;span class="kwrd"&gt;new&lt;/span&gt; Timer(ExecuteEvery72Hours, &lt;span class="kwrd"&gt;null&lt;/span&gt;, TimeSpan.FromHours(72), TimeSpan.FromHours(72));
  }
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteEvery72Hours()
  {
    &lt;span class="rem"&gt;// do something important&lt;/span&gt;
  }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a bloody rotten idea, let us see why…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What happens if your application is recycled every 29 hours?&lt;/li&gt;
&lt;li&gt;What happens if your application is always on, but during that 72 hour call, it was offline?&lt;/li&gt;
&lt;li&gt;What happens if your task actually takes more than 72 hours to run?&lt;/li&gt;
&lt;li&gt;What happens if the task fails? &lt;/li&gt;
&lt;li&gt;How do you report errors, warnings, etc?&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Scheduling is a &lt;em&gt;hard &lt;/em&gt;problem. There are a &lt;em&gt;lot&lt;/em&gt; of things that you actually need to consider. And the code above is really considering none of them. I would be very surprised if something like that &lt;em&gt;ever&lt;/em&gt; run. in production. It most certainly can’t be made to run reliably.&lt;/p&gt;
&lt;p&gt; Things that run every X time, where X is a long time (hours / days) tend to be pretty important. In some of the systems that we wrote, that include doing things like updating VAT and interest rates, pulling from external source, generating the weekly report, etc.&lt;/p&gt;
&lt;p&gt;You do &lt;em&gt;not&lt;/em&gt; want this to be messed up.&lt;/p&gt;
&lt;p&gt;If you need to do anything like that, make use of the builtin scheduling features of the OS you are running on (Windows Task Scheduler is an amazingly full featured, and cron isn’t bad if you are running on Linux). If you still insist on doing this in code, at the very least do something like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimedTask
{
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Timer Timer;
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Init()
  {
    Timer = &lt;span class="kwrd"&gt;new&lt;/span&gt; Timer(()=&amp;gt;
    {
      &lt;span class="kwrd"&gt;if&lt;/span&gt;( (DateTime.UtcNow - GetLastExecutedTime()) &amp;gt; 72)
        ExecuteEvery72Hours();
    }, &lt;span class="kwrd"&gt;null&lt;/span&gt;, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
  }
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteEvery72Hours()
  {
    &lt;span class="rem"&gt;// do something important&lt;/span&gt;
  }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This still has a lot of problems, but at least it it solving some crucial problems for you (note that GetLastExecutedTime has to be a persisted value).&lt;/p&gt;
&lt;p&gt;Of course, if you need something like this in your code, you have better use something like Quartz, instead. Don’t roll your own. Sure, this is ten lines of code to do so, but as I said, this is the very basics, and it gets complex &lt;em&gt;really &lt;/em&gt;fast.&lt;/p&gt;</description><link>http://ayende.com/blog/155489/rotten-scheduling-donrsquo-t-roll-your-own?key=89b941e1-86d7-443e-a93c-28ed0703bfc2</link><guid>http://ayende.com/blog/155489/rotten-scheduling-donrsquo-t-roll-your-own?key=89b941e1-86d7-443e-a93c-28ed0703bfc2</guid><pubDate>Mon, 14 May 2012 09:00:00 GMT</pubDate></item><item><title>Rotten Scheduling</title><description>&lt;p&gt;“We need to run a specific task every 72 hours, I thought about this approach…”&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimedTask
{
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Timer Timer;
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Init()
  {
    Timer = &lt;span class="kwrd"&gt;new&lt;/span&gt; Timer(ExecuteEvery72Hours, &lt;span class="kwrd"&gt;null&lt;/span&gt;, TimeSpan.FromHours(72), TimeSpan.FromHours(72));
  }
  
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ExecuteEvery72Hours()
  {
    &lt;span class="rem"&gt;// do something important&lt;/span&gt;
  }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let us assume that this code is being called properly. Why is this a bloody rotten idea?&lt;/p&gt;</description><link>http://ayende.com/blog/155457/rotten-scheduling?key=47a203dc-eb07-448a-82e3-2c1919704db3</link><guid>http://ayende.com/blog/155457/rotten-scheduling?key=47a203dc-eb07-448a-82e3-2c1919704db3</guid><pubDate>Fri, 11 May 2012 09:00:00 GMT</pubDate></item><item><title>Reviewing Xenta and wishing I hadn&amp;rsquo;t</title><description>&lt;p&gt;&lt;a href="http://xenta.codeplex.com/team/view"&gt;Xenta Framework&lt;/a&gt; is the extensible enterprise n-tier application framework with multilayered architecture.&lt;/p&gt; &lt;p&gt;I was asked by the coordinator for the project to review it.&lt;/p&gt; &lt;p&gt;This isn’t going to take long. I looked at the code, and I got this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_thumb.png" width="235" height="134"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I am sure you remember the last time when I run into something like this, except that the number of projects at that solution was a quarter of what we had here, and I already had to hold my nose.&lt;/p&gt; &lt;p&gt;Looking a bit deeper:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_thumb_1.png" width="325" height="380"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here is a hint, you &lt;em&gt;are&lt;/em&gt; allowed to have more than one class per project. &lt;/p&gt; &lt;p&gt;Having that many project is a nightmare in trying to manage them. Finding things, actually making &lt;em&gt;use&lt;/em&gt; of how things work. Not to mention that the level of abstractness required to support that is giving me a headache.&lt;/p&gt; &lt;p&gt;This is still without looking at the code, mind.&lt;/p&gt; &lt;p&gt;Now, let us look at the actual code. I like to start the controllers. The following code is from ForumController:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[HttpPost, ValidateInput(&lt;span class="kwrd"&gt;false&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Update(&lt;span class="kwrd"&gt;int&lt;/span&gt; forumID, FormCollection form)
{
    ForumModel m = &lt;span class="kwrd"&gt;new&lt;/span&gt; ForumModel()
    {
        ForumID = forumID
    };

&lt;font style="background-color: #ffff00"&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(!m.Load())&lt;/font&gt;
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; HttpNotFound();
    }

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(TryUpdateModel&amp;lt;ForumModel&amp;gt;(m, &lt;span class="str"&gt;"Model"&lt;/span&gt;, form))
    {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
&lt;font style="background-color: #ffff00"&gt;            m.Update();&lt;/font&gt;
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt;(Exception ex)
        {
            ModelState.AddModelError(&lt;span class="str"&gt;"API"&lt;/span&gt;, ex);
        }
    }

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(!ModelState.IsValid)
    {
        TempData.OperationStatus(&lt;span class="str"&gt;"Failed"&lt;/span&gt;);
        TempData.PersistObject(&lt;span class="str"&gt;"Model"&lt;/span&gt;, m);
        TempData.PersistModelState(ModelState);
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        TempData.OperationStatus(&lt;span class="str"&gt;"Success"&lt;/span&gt;);
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(&lt;span class="str"&gt;"Edit"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt;
    {
        ForumID = m.ForumID
    });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Seriously, I haven’t seen this style of architecture in a while. Let us dig deeper:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Update()
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(ForumApiClient api = &lt;span class="kwrd"&gt;new&lt;/span&gt; ForumApiClient())
    {
        var dto = api.UpdateForum(ForumID, ParentForumID, DisplayOrder, Flags);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; Load(dto);
    }
}

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Load()
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(ForumApiClient api = &lt;span class="kwrd"&gt;new&lt;/span&gt; ForumApiClient())
    {
        var dto = api.GetForum(ForumID);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; Load(dto);
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;In case you are wondering, those are on the ForumModel class.&lt;/p&gt;
&lt;p&gt;This piece of code is from the ForumPostModel class, it may look familiar:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Load()
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(ForumApiClient api = &lt;span class="kwrd"&gt;new&lt;/span&gt; ForumApiClient())
    {
        var dto = api.GetPost(PostID);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; Load(dto);
    }
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This ForumApiClient is actually a WCF Proxy class, which leads us to this interface:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Reviewing-Xenta_BAF4/image_thumb_2.png" width="1075" height="894"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I won’t comment on this any further, but will go directly to ForumApiService, where we actually update a forum using the following code:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ForumDto UpdateForum(&lt;span class="kwrd"&gt;int&lt;/span&gt; forumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; parentForumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; displayOrder,
    ForumFlags flags)
{
    ForumService forumService = Infrastructure.Component&amp;lt;ForumService&amp;gt;();

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(forumService == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException(&lt;span class="kwrd"&gt;new&lt;/span&gt; FaultReason(&lt;span class="str"&gt;"forum service"&lt;/span&gt;), &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultCode(ErrorCode.Infrastructure.ToString()));
    }

    &lt;span class="kwrd"&gt;try&lt;/span&gt;
    {
        ForumEntity entity = forumService.UpdateForum(forumID, parentForumID, displayOrder, flags, DateTime.UtcNow);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; Map(entity);
    }
    &lt;span class="kwrd"&gt;catch&lt;/span&gt;(XentaException ex)
    {
         &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultException(&lt;span class="kwrd"&gt;new&lt;/span&gt; FaultReason(ex.Message), &lt;span class="kwrd"&gt;new&lt;/span&gt; FaultCode(ex.Code.ToString()));
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Infrastructure.Component represent a &lt;em&gt;home grown&lt;/em&gt; service locator. Note that we have manual exception handling for absolutely no reason whatsoever (you can do this in a behavior &lt;em&gt;once&lt;/em&gt;, and since this is repeated for &lt;em&gt;each and every one of the methods&lt;/em&gt;…).&lt;/p&gt;
&lt;p&gt;I apologize in advance, but here is the full UpdateForum method:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ForumEntity UpdateForum(&lt;span class="kwrd"&gt;int&lt;/span&gt; forumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; parentForumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; displayOrder,
    ForumFlags flags, 
    DateTime updatedOn)
{
    ForumEntity oldForum = GetForum(forumID);
            
    &lt;span class="kwrd"&gt;if&lt;/span&gt;(oldForum == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; XentaException(ErrorCode.NotFound, &lt;span class="str"&gt;"forum"&lt;/span&gt;);
    }

    ForumEntity parentForum = &lt;span class="kwrd"&gt;null&lt;/span&gt;;

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(parentForumID != 0)
    {
        parentForum = GetForum(parentForumID);

        &lt;span class="kwrd"&gt;if&lt;/span&gt;(parentForum == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; XentaException(ErrorCode.NotFound, &lt;span class="str"&gt;"forum"&lt;/span&gt;);
        }

        ForumEntity tmp = parentForum;

&lt;font style="background-color: #ffff00"&gt;    HierarchyCheck:&lt;/font&gt;

        &lt;span class="kwrd"&gt;if&lt;/span&gt;(tmp.ForumID == forumID)
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; XentaException(ErrorCode.InvalidArgument, &lt;span class="str"&gt;"parentForumID"&lt;/span&gt;);
        }
        &lt;span class="kwrd"&gt;if&lt;/span&gt;(tmp.ParentForumID != 0)
        {
            tmp = tmp.Parent;

       &lt;font style="background-color: #ffff00"&gt;     &lt;span class="kwrd"&gt;goto&lt;/span&gt; HierarchyCheck;
&lt;/font&gt;        }
    }

    ForumEntity newForum = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
    &lt;span class="kwrd"&gt;bool&lt;/span&gt; res = Provider.UpdateForum(forumID,
        parentForumID,
        oldForum.LastTopicID,
        oldForum.TopicCount,
        oldForum.PostCount,
        displayOrder,
        flags,
        oldForum.CreatedOn,
        updatedOn);

    &lt;span class="kwrd"&gt;if&lt;/span&gt;(res)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt;(Cache != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            Cache.Remove(&lt;span class="str"&gt;"ForumService_GetForum_{0}"&lt;/span&gt;, oldForum.ForumID);
        }

        newForum = GetForum(forumID);

        &lt;span class="kwrd"&gt;if&lt;/span&gt;(EventBroker != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            EventBroker.Publish&amp;lt;PostEntityUpdate&amp;lt;ForumEntity&amp;gt;&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; PostEntityUpdate&amp;lt;ForumEntity&amp;gt;(newForum, oldForum));
        }
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; newForum;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, it &lt;em&gt;is&lt;/em&gt; a goto there, for the life of me I can’t figure out why.&lt;/p&gt;
&lt;p&gt;Note that there is also this Provider in here, which is an IForumProvider, which is implemented by… ForumProvider, which looks like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; UpdateForum(&lt;span class="kwrd"&gt;int&lt;/span&gt; forumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; parentForumID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; lastTopicID,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; topicCount,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; postCount,
    &lt;span class="kwrd"&gt;int&lt;/span&gt; displayOrder,
    ForumFlags flags,
    DateTime createdOn,
    DateTime updatedOn)
{
    &lt;span class="kwrd"&gt;bool&lt;/span&gt; res = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

    &lt;span class="kwrd"&gt;using&lt;/span&gt;(DbCommand cmd = DataSource.GetStoredProcCommand(&lt;span class="str"&gt;"fwk_Forums_Update"&lt;/span&gt;))
    {
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"ForumID"&lt;/span&gt;, forumID);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"ParentForumID"&lt;/span&gt;, parentForumID);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"LastTopicID"&lt;/span&gt;, lastTopicID);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"TopicCount"&lt;/span&gt;, topicCount);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"PostCount"&lt;/span&gt;, postCount);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"DisplayOrder"&lt;/span&gt;, displayOrder);
        SqlServerHelper.SetInt32(DataSource, cmd, &lt;span class="str"&gt;"Flags"&lt;/span&gt;, (&lt;span class="kwrd"&gt;int&lt;/span&gt;)flags);
        SqlServerHelper.SetDateTime(DataSource, cmd, &lt;span class="str"&gt;"CreatedOn"&lt;/span&gt;, createdOn);
        SqlServerHelper.SetDateTime(DataSource, cmd, &lt;span class="str"&gt;"UpdatedOn"&lt;/span&gt;, updatedOn);

        res = DataSource.ExecuteNonQuery(cmd) &amp;gt; 0;
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; res;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;And… this is about it guys.&lt;/p&gt;
&lt;p&gt;I checked the source control, and the source control history for this goes back only to the beginning of February 2012. I assume that this is older than this, because the codebase is pretty large.&lt;/p&gt;
&lt;p&gt;But to summarize, what we actually have is a highly abstracted project, a &lt;em&gt;lot&lt;/em&gt; of abstraction. A lot of really bad code even if you ignore the abstractions, seemingly modern codebase that still uses direct ADO.Net for pretty much everything, putting a WCF service in the middle of the application just for the fun of it.&lt;/p&gt;
&lt;p&gt;Tons of code dedicated to error handling, caching, etc. All of which can be handled as cross cutting concerns.&lt;/p&gt;
&lt;p&gt;This is the kind of application that I would expect to see circa 2002, not a decade later.&lt;/p&gt;
&lt;p&gt;And please note, I actually got the review request exactly 34 minutes ago. I didn’t review the entire application (nor do I intend to). I merely took a reprehensive* vertical slide of the app and followed up on that.&lt;/p&gt;
&lt;p&gt;*Yes, this is intentional.&lt;/p&gt;</description><link>http://ayende.com/blog/155073/reviewing-xenta-and-wishing-i-hadnrsquo-t?key=ee820864-79e7-4ad3-b5a7-43bc23624c02</link><guid>http://ayende.com/blog/155073/reviewing-xenta-and-wishing-i-hadnrsquo-t?key=ee820864-79e7-4ad3-b5a7-43bc23624c02</guid><pubDate>Thu, 10 May 2012 09:00:00 GMT</pubDate></item><item><title>The best multi threading debugging tool is Microsoft Excel</title><description>&lt;p&gt;In any system that gets to a certain size, especially one that is multi threaded, there are a certain class of bugs that are &lt;em&gt;really &lt;/em&gt;a bitch to figure out. &lt;/p&gt; &lt;p&gt;They are usually boil down to some sort of a race condition. I have been doing that recently, trying to fix a bunch of race conditions in RavenDB. The problem with race conditions is that they are incredibly hard to reproduce, and even when you can reproduce them, you can’t really &lt;em&gt;debug them&lt;/em&gt;. &lt;/p&gt; &lt;p&gt;I came up with the following test harness to try to &lt;a href="https://github.com/ayende/ravendb/blob/27564b0e543051b298f8716e5934c7bea812a4df/Raven.Tryouts/Program.cs"&gt;narrow things down&lt;/a&gt;. Basically, create a test case that sometimes fails, and run it a thousand times.&lt;/p&gt; &lt;p&gt;Odds are that you’ll get the failure, but that isn’t the important bit. The important bit is that you setup logging properly. In my case, I set things up so the logging output to CSV and each test run had a different file.&lt;/p&gt; &lt;p&gt;This gives me output that looks like this:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;23:54:34.5952,Raven.Database.Server.HttpServer,Debug,Request #&amp;nbsp; 10: GET&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;nbsp;&amp;nbsp;&amp;nbsp; 12 ms - &amp;lt;default&amp;gt;&amp;nbsp; - 200 - /indexes/dynamic/Companies?query=&amp;amp;start=0&amp;amp;pageSize=1&amp;amp;aggregation=None,,11&lt;br&gt;23:54:34.5952,Raven.Client.Document.SessionOperations.QueryOperation,Debug,"Stale query results on non stale query '' on index 'dynamic/Companies' in '&lt;a href="http://reduction:8079/'"&gt;http://reduction:8079/'&lt;/a&gt;, query will be retried, index etag is: bcf0fed1-d975-43b4-bfb7-65221ef06b99",,1&lt;br&gt;23:54:34.5952,Raven.Database.Indexing.WorkContext,Debug,"No work was found, workerWorkCounter: 10, for: TasksExecuter, will wait for additional work",,6&lt;br&gt;23:54:34.5952,Raven.Database.Indexing.WorkContext,Debug,Incremented work counter to 11 because: WORK BY IndexingExecuter,,12&lt;br&gt;23:54:34.5952,Raven.Database.Indexing.WorkContext,Debug,"No work was found, workerWorkCounter: 11, for: TasksExecuter, will wait for additional work",,6&lt;br&gt;23:54:34.5952,Raven.Database.Indexing.WorkContext,Debug,"No work was found, workerWorkCounter: 11, for: ReducingExecuter, will wait for additional work",,21&lt;br&gt;23:54:34.5952,Raven.Database.Indexing.WorkContext,Debug,"No work was found, workerWorkCounter: 11, for: IndexingExecuter, will wait for additional work",,12&lt;br&gt;23:54:34.6952,Raven.Client.Document.SessionOperations.QueryOperation,Debug,Executing query '' on index 'dynamic/Companies' in '&lt;a href="http://reduction:8079/',,1"&gt;http://reduction:8079/',,1&lt;/a&gt;&lt;br&gt;23:54:34.8172,Raven.Database.Indexing.Index.Querying,Debug,Issuing query on index Temp/Companies for all documents,,11&lt;br&gt;23:54:34.8172,Raven.Storage.Esent.StorageActions.DocumentStorageActions,Debug,Document with key 'companies/1' was found,,11&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Not really helpful in figure out what is going on, right? Except for one tiny thing, we load them to Excel, and we use conditional formatting to get things to look like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/The-best-multi-threading-debugging-tool_1502F/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/The-best-multi-threading-debugging-tool_1502F/image_thumb.png" width="1239" height="544"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The reason this is so helpful? You can actually see the threads interleaving. This usually help me get to roughly the right place, and then I can add additional logging so I can figure out better what is &lt;em&gt;actually&lt;/em&gt; going on.&lt;/p&gt; &lt;p&gt;I was able to detect and fix several race conditions using this approach. &lt;/p&gt; &lt;p&gt;And yes, I know that this is basically printf() debugging. But at least it is printf() debugging with pretty colors.&lt;/p&gt;</description><link>http://ayende.com/blog/154817/the-best-multi-threading-debugging-tool-is-microsoft-excel?key=4868300a-e80b-4c00-9fc8-84f988cf16a4</link><guid>http://ayende.com/blog/154817/the-best-multi-threading-debugging-tool-is-microsoft-excel?key=4868300a-e80b-4c00-9fc8-84f988cf16a4</guid><pubDate>Wed, 09 May 2012 09:00:00 GMT</pubDate></item><item><title>Answering customer questions</title><description>&lt;p&gt;This made me laugh:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Answering-customer-questions_EDD4/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Answering-customer-questions_EDD4/image_thumb.png" width="1007" height="449"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And yes, I am aware that laughing at my own action is… strange.&lt;/p&gt;</description><link>http://ayende.com/blog/154369/answering-customer-questions?key=36bc85bc-591f-4a02-936e-d96b1415de01</link><guid>http://ayende.com/blog/154369/answering-customer-questions?key=36bc85bc-591f-4a02-936e-d96b1415de01</guid><pubDate>Tue, 08 May 2012 09:00:00 GMT</pubDate></item><item><title>Testing Rhino Service Bus applications</title><description>&lt;p&gt;One of the really nice things about Rhino Service Bus applications is that we have created a structured way to handle inputs and outputs. You have messages coming in and out, as well as the endpoint local state to deal with. You don’t have to worry about how to deal with external integration points, because those are already going over messages.&lt;/p&gt; &lt;p&gt;And when you have basic input/output figured out, you are pretty much done.&lt;/p&gt; &lt;p&gt;For example, let us see the code that handles extending trail licenses in our ordering system:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ExtendTrialLicenseConsumer : ConsumerOf&amp;lt;ExtendTrialLicense&amp;gt;
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IDocumentSession Session { get; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IServiceBus Bus { get; set; }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Consume(ExtendTrialLicense message)
    {
        var productId = message.ProductId ?? &lt;span class="str"&gt;"products/"&lt;/span&gt; + message.Profile;
        var trial = Session.Query&amp;lt;Trial&amp;gt;()
            .Where(x =&amp;gt; x.Email == message.Email &amp;amp;&amp;amp; x.ProductId == productId)
            .FirstOrDefault();

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (trial == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        
        trial.EndsAt = DateTime.Today.AddDays(message.Days);
        Bus.Send(&lt;span class="kwrd"&gt;new&lt;/span&gt; NewTrial
        {
            ProductId = productId,
            Email = trial.Email,
            Company = trial.Company,
            FullName = trial.Name,
            TrackingId = trial.TrackingId
        });
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;How do we test something like this? As it turns out, quite easily:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TrailTesting : ConsumersTests
{
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrepareData(IDocumentSession session)
    {
        session.Store(&lt;span class="kwrd"&gt;new&lt;/span&gt; Trial
        {
            Email = &lt;span class="str"&gt;"you@there.gov"&lt;/span&gt;,
            EndsAt = DateTime.Today,
            ProductId = &lt;span class="str"&gt;"products/nhprof"&lt;/span&gt;
        });
    }

    [Fact]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Will_update_trial_date()
    {
        Consume&amp;lt;ExtendTrialLicenseConsumer, ExtendTrialLicense&amp;gt;(&lt;span class="kwrd"&gt;new&lt;/span&gt; ExtendTrialLicense
        {
            ProductId = &lt;span class="str"&gt;"products/nhprof"&lt;/span&gt;,
            Days = 30,
            Email = &lt;span class="str"&gt;"you@there.gov"&lt;/span&gt;,
        });

        &lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = documentStore.OpenSession())
        {
            var trial = session.Load&amp;lt;Trial&amp;gt;(1);
            Assert.Equal(DateTime.Today.AddDays(30), trial.EndsAt);
        }
    }

    &lt;span class="rem"&gt;// more tests here&lt;/span&gt;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;All the magic happens in the base class, though:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ConsumersTests : IDisposable
{
    &lt;span class="kwrd"&gt;protected&lt;/span&gt; IDocumentStore documentStore;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; IServiceBus Bus = &lt;span class="kwrd"&gt;new&lt;/span&gt; FakeBus();

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; ConsumersTests()
    {
        documentStore = &lt;span class="kwrd"&gt;new&lt;/span&gt; EmbeddableDocumentStore
        {
            RunInMemory = &lt;span class="kwrd"&gt;true&lt;/span&gt;,
            Conventions =
                {
                    DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites
                }
        }.Initialize();

        IndexCreation.CreateIndexes(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Products_Stats).Assembly, documentStore);

        Products.Create(documentStore);
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = documentStore.OpenSession())
        {
            PrepareData(session);
            session.SaveChanges();
        }
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; T ConsumeSentMessage&amp;lt;T&amp;gt;()
    {
        var fakeBus = ((FakeBus)Bus);
        &lt;span class="kwrd"&gt;object&lt;/span&gt; o = fakeBus.Messages.Where(x =&amp;gt; x.GetType() == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(T)).First();

        fakeBus.Messages.Remove(o);
        &lt;span class="kwrd"&gt;return&lt;/span&gt; (T) o;
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Consume&amp;lt;TConsumer, TMsg&amp;gt;(TMsg msg)
        &lt;span class="kwrd"&gt;where&lt;/span&gt; TConsumer : ConsumerOf&amp;lt;TMsg&amp;gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt;()
    {
        var foo = &lt;span class="kwrd"&gt;new&lt;/span&gt; TConsumer();

        &lt;span class="kwrd"&gt;using&lt;/span&gt; (var documentSession = documentStore.OpenSession())
        {
            Set(foo, documentSession);
            Set(foo, Bus);
            Set(foo, documentStore);

            foo.Consume(msg);

            documentSession.SaveChanges();
        }
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Set&amp;lt;T,TValue&amp;gt;(T foo, TValue &lt;span class="kwrd"&gt;value&lt;/span&gt;)
    {
        PropertyInfo firstOrDefault = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(T).GetProperties().FirstOrDefault(x=&amp;gt;x.PropertyType==&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(TValue));
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (firstOrDefault == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;return&lt;/span&gt;;
        firstOrDefault.SetValue(foo, &lt;span class="kwrd"&gt;value&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrepareData(IDocumentSession session)
    {
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose()
    {
        documentStore.Dispose();
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;And here are the relevant details for the FakeBus implementation:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FakeBus : IServiceBus
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;  Messages = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Send(&lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[] messages)
    {
        Messages.AddRange(messages);
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, admittedly, this is a fairly raw approach and we can probably do better. This is basically hand crafted auto mocking for consumers, and I don’t like the Consume&amp;lt;TConsumer,TMsg&amp;gt;() syntax very much. But it works, it is simple and it doesn’t really gets in the way.&lt;/p&gt;
&lt;p&gt;I won’t say it is &lt;em&gt;the&lt;/em&gt; way to go about it, but it is certainly easier than many other efforts that I have seen. We just need to handle the inputs &amp;amp; outputs and have a way to look at the local state, and you are pretty much done.&lt;/p&gt;</description><link>http://ayende.com/blog/152993/testing-rhino-service-bus-applications?key=ee11d848-dadc-4923-b8de-78e6a7813888</link><guid>http://ayende.com/blog/152993/testing-rhino-service-bus-applications?key=ee11d848-dadc-4923-b8de-78e6a7813888</guid><pubDate>Mon, 07 May 2012 09:00:00 GMT</pubDate></item><item><title>Strange production errors</title><description>&lt;p&gt;The following code cause a &lt;em&gt;really&lt;/em&gt; strange error in production:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;new MailAddress("test@gmail.​com");&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The specified string is not in the form required for an e-mail address.&lt;/p&gt; &lt;p&gt;Huh?!&lt;/p&gt; &lt;p&gt;Obviously it is!&lt;/p&gt; &lt;p&gt;After immediately leaping to the conclusion that .NET is crap and I should immediately start writing my own virtual machine, I decided to dig a little deeper:&lt;/p&gt; &lt;table&gt; &lt;tbody&gt; &lt;tr&gt; &lt;th&gt;Character&lt;/th&gt; &lt;th&gt;Code&lt;/th&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;t&lt;/td&gt; &lt;td&gt;116&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;e&lt;/td&gt; &lt;td&gt;101&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;s&lt;/td&gt; &lt;td&gt;115&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;t&lt;/td&gt; &lt;td&gt;116&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;@&lt;/td&gt; &lt;td&gt;64&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;g&lt;/td&gt; &lt;td&gt;103&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;m&lt;/td&gt; &lt;td&gt;109&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;a&lt;/td&gt; &lt;td&gt;97&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;i&lt;/td&gt; &lt;td&gt;105&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;l&lt;/td&gt; &lt;td&gt;108&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;.&lt;/td&gt; &lt;td&gt;46&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;&lt;strong&gt;&lt;font style="background-color: #ffff00"&gt;8203&lt;/font&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;c&lt;/td&gt; &lt;td&gt;99&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;o&lt;/td&gt; &lt;td&gt;111&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;m&lt;/td&gt; &lt;td&gt;109&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;8203 stands for U+200B or zero width space.&lt;/p&gt; &lt;p&gt;I guess that someone with a software testing background decided to get medieval on one of our systems.&lt;/p&gt;</description><link>http://ayende.com/blog/153761/strange-production-errors?key=2d4a0f97-e20c-4c37-9a7b-bf2c2921d1b4</link><guid>http://ayende.com/blog/153761/strange-production-errors?key=2d4a0f97-e20c-4c37-9a7b-bf2c2921d1b4</guid><pubDate>Fri, 04 May 2012 09:00:00 GMT</pubDate></item><item><title>I hate this code</title><description>&lt;p&gt;I &lt;em&gt;really &lt;/em&gt;hate this code, it is so &lt;em&gt;stupid&lt;/em&gt; it makes my head hurt, and it have so much important factors in it. In particular, there is a lot of logic in here.&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/I-hate-this-code_F857/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/I-hate-this-code_F857/image_thumb.png" width="1110" height="511"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You might not see it as such, but a lot of this is actually &lt;em&gt;quite&lt;/em&gt; important, default values, config parsing, decisions. &lt;/p&gt; &lt;p&gt;This is important. And it is all handled in a a few methods that goes on forever and hide important details in the tediousness of parameter unpacking.&lt;/p&gt; &lt;p&gt;This approach works if you have 5 parameters, not when you have 50.&lt;/p&gt;</description><link>http://ayende.com/blog/154561/i-hate-this-code?key=da4fb8d4-69de-45f0-bfe4-1d9f61f58b0c</link><guid>http://ayende.com/blog/154561/i-hate-this-code?key=da4fb8d4-69de-45f0-bfe4-1d9f61f58b0c</guid><pubDate>Thu, 03 May 2012 09:00:00 GMT</pubDate></item><item><title>Thou shall not delete</title><description>&lt;p&gt;Ouch!&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult DeleteComment(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)
{
  var userComment = RavenSession.Load&amp;lt;UserComment&amp;gt;(id);

  &lt;span class="kwrd"&gt;if&lt;/span&gt; (userComment == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpStatusCodeResult(204);

  var user = RavenSession.GetUser(User.Identity.Name);
  &lt;span class="kwrd"&gt;if&lt;/span&gt;(user == &lt;span class="kwrd"&gt;null&lt;/span&gt; || (user.Role != UserRole.Moderator &amp;amp;&amp;amp; user.Role != UserRole.Admin))
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpStatusCodeResult(403, &lt;span class="str"&gt;"You must be logged in as moderator or admin to be able to delete comments"&lt;/span&gt;);

  RavenSession.Delete(user);

  &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpStatusCodeResult(204);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;</description><link>http://ayende.com/blog/154977/thou-shall-not-delete?key=a86334f4-49a8-4d6d-aca1-848c98741867</link><guid>http://ayende.com/blog/154977/thou-shall-not-delete?key=a86334f4-49a8-4d6d-aca1-848c98741867</guid><pubDate>Wed, 02 May 2012 09:00:00 GMT</pubDate></item><item><title>And sometimes Things Just Works</title><description>&lt;p&gt;I am in the process of writing an article about RavenDB, and I just wrote the following code to demonstrate RavenDB schema less nature:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = documentStore.OpenSession())
{
    session.Store(&lt;span class="kwrd"&gt;new&lt;/span&gt; Customer
    {
        Name = &lt;span class="str"&gt;"Joe Smith"&lt;/span&gt;,
        Attributes =
            {
                {&lt;span class="str"&gt;"IsAnnoyingCustomer"&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;},
                {&lt;span class="str"&gt;"SatisfactionLevel"&lt;/span&gt;, 8.7},
                {&lt;span class="str"&gt;"LicensePlate"&lt;/span&gt;, &lt;span class="str"&gt;"B7D-12JA"&lt;/span&gt;}
            }
    });

    session.SaveChanges();
}

&lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = documentStore.OpenSession())
{
    var customers = session.Query&amp;lt;Customer&amp;gt;()
        .Where(x =&amp;gt; x.Attributes[&lt;span class="str"&gt;"IsAnnoyingCustomer"&lt;/span&gt;].Equals(&lt;span class="kwrd"&gt;true&lt;/span&gt;))
        .ToList();

    Console.WriteLine(customers.Count);

    session.SaveChanges();
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;This &lt;em&gt;worked&lt;/em&gt;, flawlessly. &lt;/p&gt;
&lt;p&gt;The amount of work that we have put into RavenDB to make such things work is really scary when you sit down to think about it.&lt;/p&gt;
&lt;p&gt;But it works, it does what I expect it to do and it doesn’t get in my way, woohoo!&lt;/p&gt;</description><link>http://ayende.com/blog/152865/and-sometimes-things-just-works?key=e94ea6a3-4b80-4b2b-b1cd-85944875771e</link><guid>http://ayende.com/blog/152865/and-sometimes-things-just-works?key=e94ea6a3-4b80-4b2b-b1cd-85944875771e</guid><pubDate>Tue, 01 May 2012 09:00:00 GMT</pubDate></item><item><title>Multi Threading Insanity</title><description>&lt;blockquote&gt; &lt;p&gt;&lt;img src="http://www.thefinancialpanner.com/wp-content/uploads/2010/12/EinsteinInsanity.jpg"&gt; &lt;p&gt;Insanity: doing the same thing over and over again and expecting different results.&lt;br&gt;&lt;a href="http://www.brainyquote.com/quotes/authors/a/albert_einstein.html"&gt;Albert Einstein&lt;/a&gt;&lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You obviously never done any multi threading work, dude!&lt;/p&gt;</description><link>http://ayende.com/blog/153793/multi-threading-insanity?key=bf22defd-c7a3-4044-a31a-e2ce153917ee</link><guid>http://ayende.com/blog/153793/multi-threading-insanity?key=bf22defd-c7a3-4044-a31a-e2ce153917ee</guid><pubDate>Mon, 30 Apr 2012 09:00:00 GMT</pubDate></item></channel></rss>
