Monthly Archives: March 2010

NServiceBus a solution for load-balancing console applications?

One of the most frustrating things to me as a software architect is evaluating a new technology for a new project, and getting the feeling in my gut that if properly applied, this new technology could solve a lot of problems, if only I had the time to fully study it and do a lot of research and development. But, I’m working on a project, and that project has a deadline, and I know it won’t happen. So instead of being unhappy with my code after finding it a year or two later (as should be the case, or you’re not learning) I’m going to be unhappy with it nearly immediately.

I’m facing a project where I need to build a highly scalable background processing service. Of course, it should be load balanced, so that maintenance can be performed on the host servers, and moreover, an architecture that allows me to scale it by applying more instances on more servers (or even more instances in the cloud) will provide me with the ultimate in scalability potential.

This is easy with a web application. We have a load balancer, and it’s very good at what it does. A web application just listens for and then processes requests. If you take it off the load balancer it will get no requests. Easy.

This is a lot more convoluted for back-end processes. It doesn’t necessarily sit back and wait for requests. It does things of its own volition. This means if there are more than one process, there needs to be some concept of who is in charge. Heartbeats between applications to know who else is alive and who is dead. And how is dead or alive defined? The fact that the server will respond to a request on port 80 will no longer cut it.

I’m currently evaluating NServiceBus and I have to say at first blush, it’s pretty impressive. I like how it essentially turns a console process into a bunch of handlers waiting for events – a lot like a web application actually, which would make it easier to load balance. If events get fed into distributors, and then multiple instances can retrieve work out of that work queue, then it makes it more straightforward – an instance will either be active and retrieving work, or it will be inactive and the other instances will make up for it, and more instances can be brought online to help scale out.

But that doesn’t completely eliminate the problem of having a master or lead process. This application, for example, needs to start its work on a schedule. If 3 processes are running, one needs to be in charge and say when to start processing on a piece of work. After that one event, the NServiceBus message handling infrastructure can take care of the rest of the scaling.

Hopefully I’ll figure this out before it’s too late for this project. If so, I’ll come back and link to it here.

301 Redirects with the IIS7 Rewrite Module

We all have drilled into us how important it is to use a 301 redirect when changing a website’s address so that the site’s page rank and other SEO goodies are preserved.  Since it’s so important, you’d think it would be easier, or maybe even straightforward to accomplish.

I recently moved this blog from a subdirectory of another domain to its very own domain, and wanted to do just that, and found it anything but easy.

People with Apache webservers have long had the ability to perform 301 redirects in a fairly straightforward manner using .htaccess files.  However, IIS users have not been so lucky.  Although I have a WordPress blog (because it’s the best out there) I am an ASP.NET developer and I need to have a Windows server playground to try stuff out in, so I have PHP 5 and .NET 3.5 running on Windows Server 2008.  So .htaccess files aren’t an option for me.

At first I tried redirecting purely with PHP inside the bounds of WordPress.  I tried multiple redirection plugins, none of which seemed to work.  They would redirect my site, but when I checked with Fiddler it would always be a 302 redirect.  Unacceptable.

I even tried monkeying directly with WordPress’s index.php file, which I was not happy about doing because I knew it would make upgrading WordPress more difficult.  Even with the following PHP-based redirect as the first few lines of the PHP file…

// Note, didn't work for me, provided for reference only
header( "HTTP/1.1 301 Moved Permanently" );
header( "Location: http://www.new-url.com" );
exit();

… I was still getting 302 redirects when checking in Fiddler. I don’t know if it’s something specifically about the interaction between IIS7 and PHP. Maybe once IIS hands off the ISAPI request to PHP, it won’t accept a 301 as a response and so it defaults to a 302. In any case, it didn’t work, and I wasn’t happy.

Enter the IIS7 Rewrite Module.  It’s not a standard part of IIS so you need to download and install it separately, but it’s beyond worth it.  It enables rewriting urls for pretty, SEO-friendly urls, but it also supports redirection as well.

At first I had trouble with the rewrite module.  I was dealing with raw Web.config files on my hosting provider’s site, not having direct access to the IIS controls themselves.  It was also difficult to find documentation on the configuration settings since everywhere you look pretty much assumes you’re working with the GUI tools in the IIS7  Manager, which I wasn’t. I tried many things, based on examples I found off the Internet or my own guesses and theories, and they all either didn’t work or gave me a big fat 500 error.

I finally found some help from URL Rewrite Module Configuration Reference on learn.iis.net, which I feel pretty safe elevating to the status of Must Read. After some more guess-and-check, I came up with the following configuration for redirecting a site hosted in a subdirectory to its own top-level primary domain:

<!-- Web.config file in subdirectory to be redirected -->
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="RedirectRule" stopProcessing="true">
          <match url="(.*)" ignoreCase="true" />
          <action type="Redirect" url="http://www.newdomain.com/{R:1}" redirectType="Permanent" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="www\.old-domain\.com" />
            </conditions>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Here are some of the things that threw me for a loop:

  • The match url is relative to the location of the web.config file. I’ve written a regular expression or two in my day, and I thought I was matching against the entire path. If the Web.config file is at /old/app/path/web.config, and you are trying to redirect /old/app/path/default.aspx, then the string you are matching against in this context is “default.aspx” without any sort of beginning slash. Therefore, the match url of (.*) matches everything in the subdirectory.
  • {R:1} looks way too similar to .NET string formatting jargon. In reality it has much more in common with regular expression replacement syntax. {R:1} means the first captured group within the regular expression (or wildcard matched * if that’s the way you want to go.) Likewise, {R:0} is the entire matched string. From what I read, {C:1} would be the first captured group within a condition regular expression (as opposed to the R for Match Rule, perhaps, although the letter R doesn’t occur anywhere near to the regular expression it matches. Whatever. In any case, I haven’t had the opportunity to utilize a C match yet.
  • Rule operates on the path and query; use conditions for domains. Or for anything else that isn’t the path, for that matter. In my case, I have one hosting account where I can post secondary domains (like this one) to a subdomain as its root. That means I need to filter for the old domains – it wouldn’t do to have the new domain redirect to itself. Rumor has it that infinite redirects are bad.
  • Try different things with the GUI in IIS7 Manager. While I didn’t find my exact answer, I learned a lot by trying different things and seeing how they were represented in the Web.config file.
  • Can I please get a list of condition variables? I haven’t been able to find a comprehensive list of variables that can be used between curly braces, but they correspond to server variables. In fact, any HTTP header can be used if you format it all uppercase, convert any dashes to underscores, and prefix it with “HTTP_”. More useful information, including even string functions, can be found by reading URL Rewrite Module Configuration Reference at length. It’s worth it.
  • If using WordPress (or other web application that can rewrite local files), make sure the Web.config file isn’t writeable. WordPress might see that the file isn’t exactly like it thinks it should be to do its own url rewriting and try to replace it under your nose. Well, not under your nose, but you might push a button that overwrites it without thinking about it, and it will probably be months before you figure out that it even happened, much less that it destroyed your page rank.

Reminder Attributes

I strongly believe that code isn’t perfect.  Ever.  There’s always some improvement that can be made, but frequently I don’t have time to do it, or for whatever reason I can’t do it.  I want to be able to remember where these things are, so that someday when I have free time (insert laugh here) I can go back and do something about it.

A bug tracking system is good, but if it’s something that exists in multiple locations it can be hard to document where all those points are in a defect report.  Even thorough documentation can be hard to track down later if refactoring or re-engineering moves code around.

Since the first version of Visual Studio, there were TODO Comments, but these are of limited usefulness.  They show up in Visual Studio’s Task List toolbar (select Task List from the View menu, then select Comments from the dropdown in the toolbar) but only if the file containing the comments is open.  What if I’m trying to do something across multiple classes and methods?

Prime example: we still have SQL Server 2000 databases.  We have a new SQL Server 2008 to migrate to, but with an ample amount of legacy code, the migration is anything but simple, and there are always more important projects with revenue attached.

In the meantime, we have features that would benefit from Common Table Expressions or Table Valued Parameters, but we can’t use them because we’re still stuck on SQL 2000 for the time being.  I need to be able to mark those chunks of code so I can find them all back someday when the database migration is complete.

Enter reminder attributes.

public class Sql2008Attribute : Attribute
{
	public string Description { get; private set; }

	public Sql2008Attribute()
	{
	}

	public Sql2008Attribute(string description)
	{
		this.Description = description;
	}
}

Creating the Description property is optional, but it allows you to make a note to yourself to specify what it is you want to do one day.  Once you declare this attribute class in your codebase, you can decorate anything with it as a little reminder to yourself.


[Sql2008("Use a table-valued parameter to execute all in one round-trip")]
public void DeleteItems(List idList)
{
	// Method splits list into batches of 50 and executes a stored 
	// procedurethat can take up to 50 parameters.  This could 
	// definitely benefit from a SQL 2008 table-valued parameter 
	// that would allow sending all of the ids to the database
	// server in one round-trip.
}

Once our database migration is complete, it will be easy for me to find all the code I’d like to update by right-clicking the Sql2008Attribute class definition, right-clicking, and selecting Find All References.