Thursday, May 14, 2009

Programaticly Configuring NServiceBus

I just started implementing a PubSub system for our company using NServiceBus. Overall if has been super easy to setup. The samples are a great starting point and everything is pretty self explanatory.


However as I was trying to roll it out into production I realized that using the standard Spring configuration wasn't going to work for us. I wanted the name of the Msmq input queue to be specified programatilcy instead of via a config file. I knew it had to be possible but I had a really tough time figuring out how to do it. All the samples I could find were about how to set things up with Spring. So I though I would share how I did it.


The standard example shows:

NServiceBus.Configure.With()
    .XmlSerializer()
    .MsmqTransport()
        .IsTransactional(false)
        .PurgeOnStartup(false)
    .UnicastBus()
        .ImpersonateSender(false)
        .LoadMessageHandlers()
    .CreateBus()
    .Start();


So to dynamically set the MsmqTransoprt values you can write the following:

Configure configure = NServiceBus.Configure.With().SpringBuilder();
 
MsmqTransport transport = configure.Configurer.ConfigureComponent<MsmqTransport>(ComponentCallModelEnum.Singleton);
 
transport.InputQueue = "DynamicQueueName";
transport.NumberOfWorkerThreads = 1;
transport.ErrorQueue = "DynamicErrorQueue";
transport.MaxRetries = 5;
 
configure
    .XmlSerializer()
    .UnicastBus()
        .ImpersonateSender(false)
        .LoadMessageHandlers()
    .CreateBus()
    .Start();

This works for me, I have no idea if that is the best practice or if there is a better way to set these values programaticly. Hopefully this helps you and saves you from some the headache I went through (it always seems pretty simple once you get it figured out). Please let me know if you know a better way to do this.

Monday, April 20, 2009

NBA Data Analysis

Awhile ago Mark Cuban posted an interesting break down of some possible inequalities in the NBA scheduling. Basically some teams had more back-to-back games and more set of 4 games in 5 nights. The assumption was that teams would do worse with less rest time.

I was interested to see if that assumption was true. The best data I could get was from Department of Statistics, University of Munich, and the SFB386 which has the entire 95/96 NBA season broken down game by game.

I wrote a simple app to analyse the data (run the test NBATests.DataSetTests.ParseTest to re-run the analysis). The results of the test are in the spread sheet stats.xlsx in the zip file. In that season there didn't appear to be any 4-in-5 sets. That must be a new invention by the NBA.

The numbers are interesting. Overall the win percentage for the league when playing the second game of a back-to-back set is 44%. When taking into account a team's overall win percentage for the season the average difference in win percentage between games that were back-to-back and those where the team had a rest night before was 7%.

8 teams did better in back-to-back games, Miami led the way, their win percentage was 15% higher in their second game.

Atlanta on the other was abysmal, their win percent dropped 39% when they had to play two games in a row.

I had the thought that better teams might be better because of their bench and thus would fair better in back-to-back games because of their depth but this doesn't appear to be the case. The r-squared value for win percent plotted against win percent difference in back-to-back games was only .015.

So overall while some teams appear to get better in back-to-back games overall I think the assumption that it is a disadvantage to have more back-to-back games is a fair one.

There are all kind of other ways to slice up the data that I didn't do but someone should:

  • Exclude games where both teams are playing back-to-back.
  • Factor in home and away win percentages and not just overall win percentage.
  • Doing some kind of qualitative analysis on the depth of the teams that year to see if that plays a factor.
Also if anyone has a data set(s) for more recent years send them over and I'll plug them in and see if these results hold year over year.

Thursday, April 16, 2009

TFS InvalidProgramException (or why software you need to install is stupid)

We are trying to includes some code that we keep in TFS source control into our builds. We also use code from AccuRev and SourceSafe. So we wanted to keep our existing build process and just have it include the TFS code instead of moving to an entirely TFS based build system.

So, like with any new tool we are including in our build process, I install it (in this case the TFS SDK) locally on my machine, get the DLLs from it and dumped them into our externals folder in AccuRev. Then I coded up the TFS integration piece and wrote some tests and everything looks like it was going wonderfully.

Then I tried to do a build on our build farm. The first call to TFS (TeamFoundationServerFactory.GetServer in this case) yielded:
Unhandled Exception: System.InvalidProgramException: Common Language Runtime detected an invalid program.
at Microsoft.TeamFoundation.Client.TeamFoundationServerFactory.GetServer(String name)

what the heck? Turns out the most common reason get this error is the TFS and x64 machines don't play well together. But in my case it was because I didn't have TFS installed on the machine I was tyring to run it on.

This is a huge pain in the butt. We build lots of versions of our software, we need to make sure that 3 years from now when we need to re-build the version from toady it will work fine. But if I have to install it on the machines instead of checking it in to source control this becomes very hard. What happens when Microsoft release an SP that changes something? What happens when TFS 2010 comes out and isn't able to install side by side with the 2008 version?

Please, please, if you are making software, especially software used for software development, make sure it can be deployed via xcopy.

Another case of this is Dofuscator, we use it now on one machine, we are pretty happy with. We would like to scale it out to all of our machines but you need to install it and register it on each machine to make it work. This is a deal breaker for us. They just a lost a bunch of licences.

I get that some programs want to control your usage of their product. But allow people to by a site licence and then deploy that via xcopy. Its more work but it will make your customers a lot happier.

Tuesday, March 31, 2009

Strong Name Verification on Windows 2k8 x64

I recently was trying to disable strong name verification on a Windows Server 2008 x64 machine. I ran the standard:
sn.exe -Vr *

which didn't seem to work. It turns out, and I have no idea why. You need set the regkey directly to make this work.

To disable strong name verification for all dlls on a machine (which is a terrible idea in most cases) add:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\*,*]


to the registry.

Saturday, March 7, 2009

A couple of ways to screw up your parallization

I had a function that needed to call a couple of long running operations.  The function has gotten unacceptable slow.  So the obvious thing to do was to thread the operations to run in parallel.  No problem, couple of lines of code and we'll be all set.  First draft:

Dictionary<Action<object>, int> functionsAndArguemnts = new Dictionary<Action<object>, int>

{

    {this.LongRunningOp1,1},

    {this.LongRunningOp2,2},

    {this.LongRunningOp3,3},

};

 

functionsAndArguemnts.Keys.Select(key =>

    {

        Thread t = new Thread(new ParameterizedThreadStart(key));

        t.Start(functionsAndArguemnts[key]);

        return t;

    }).ToList().ForEach(thread=>thread.Join());


This showed no performance improvement.  I was surprised for a second and then, thankfully I figured it out.  I was a victim of the power of the yield return.  The select will yield return the results and so each thread would only start when we tryed to join to it. Doh!  Easy enough to fix though:


functionsAndArguemnts.Keys.Select(key =>

    {

        Thread t = new Thread(new ParameterizedThreadStart(key));

        t.Start(functionsAndArguemnts[key]);

        return t;

    }).ToList().ForEach(thread=>thread.Join());


So the next way I screwed up my parallization was a bit less subtle.  I had a function that handled all the synchronization and error handling (the error handling bit I left out of this example) for some threading I was doing.  It takes in a function and a argument and calls the function with the argument and then puts all the results in a list.


private List<int> ints = new List<int>();

public void DoStuff(Func<string, IEnumerable<int>> action, string argument)

{

    lock (this.ints)

    {

        this.ints.AddRange(action(argument));

    }

}


Once again, silly me.  No parallization is happening.  And once again easy fix:


public void DoStuff(Func<string, IEnumerable<int>> action, string argument)

{

    IEnumerable<int> results = action(argument);

    lock (this.ints)

    {

        this.ints.AddRange(results);

    }

}


The moral of the story, parallization is still hard.


An interesting link on some lock trivia that highlights the point:  Locks and exceptions don't mix.

I am looking forward to the work in C# 4.0 around threading, would make some things simpler.