It’s my birthday today and I’m 34 years old. A hearty thanks to the folks who have sent me good birthday wishes via the various communication mechanisms at their disposal including, but not limited to: Twitter, Facebook, email, snail mail, text message, BlackBerry messenger, Google Chat, and telephone. I do appreciate it.

The day ain’t over yet, but it’s been a good birthday so far.

Last night my parents came by for a little while to visit. It was good to see them and they left a funny “Dadcat” shirt (because my girl cat lays on my stomach just like the cat on the shirt), some cool Hawaiian boxer shorts made from bamboo, and a pin from the Maui Hard Rock Cafe (I have a small collection).

One of our cat boys, Stan, started the day out by wishing me a happy birthday very loudly from outside the bedroom door. He provided an enthusiastic serenade about the day from 5:00a all the way until 6:00a when Jenn got up to get ready for work. He is outside the office door right now wishing me a happy birthday still. Still loud. Still enthusiastic. Lovely.

Jenn gave me her gifts before she left:

I’ve got the day off from work, which means I can do whatever I want, including not putting any gel in my hair. My head looks like a dandelion puff, but I’m cool with that.

After I’m done here, I’m going to go to McDonald’s and treat myself to a bacon, egg, and cheese McGriddle, my favorite. Then I’ll probably do some more mundane things like shopping at Costco, but I’ll be savoring the memory of that McGriddle, man.

I don’t know if we have some friends coming over tonight or not. If so, cool. Either way, I may end up rolling some Borderlands with my dad. We’re trying to crack level 40. Since the DLC for it is on sale next week, we’ll probably grab it then.

Tomorrow… well, there’s a family gathering, but it’s not for my birthday - it’s for my cousin who recently passed. Sort of a downer, so we’ll just move on. (Also, I anticipate a lot of “What have you been up to?” questions which I can’t answer because how do you explain “implementing multitenant dependency injection in Autofac” to a non-technical person?)

Sunday I do have some friends coming over and I anticipate there being some Rocking and Banding the likes of which have never been seen before. Or maybe we’ll just get some dinner. Either way, that’ll be fun.

So, again, thanks to those who’ve sent in birthday wishes. It’s time for me to go get my McGriddle!

For the second year in a row, Western Display Fireworks decided to trust Jenn and I to run our own show. This year we were in Happy Valley, OR.

The show was a little smaller than last year with around 300 shells and seven pre-fused boxes. It lasted about 18 minutes.

We had a good crew and both setup and cleanup went surprisingly quickly. Some of the crew are folks who had worked with me in previous years, some were new.

Here are the edited highlights:

One of my crewmembers, Alex, also took some great photos.

We had a lot of visits from city and state officials this year, way more than any other show I’ve ever been on. Fire crews checking things out, asking where to be stationed; police figuring out what the best way to secure things might be; the fire marshal running around with his checklist making sure we’re doing things to spec… it was pretty intimidating, to be honest. Shows how much they’re cracking down on this stuff. I guess they had something like 12 police units out patrolling for illegal fireworks that night.

From a retrospective standpoint there are a couple of things to mention:

  • I still hate driving the truck. Just thinking about driving a moving truck makes me tense up. Lighting explosives next to my head? No problem. Driving the moving truck? Problem. Jenn is a freaking truck-driving maniac so she took care of it most of the time, but I still had ample opportunity to tense up behind the wheel.
  • It is really, really hard to get a crew together. Really hard. Beyond hard. We had a really great crew this year, just as we did last year, but even giving people over a month’s notice it’s difficult to get folks to commit to being there… and you really need people you can count on to be there, or the whole thing will be a tough stunt to pull off. People cancel at the last minute, people don’t show up… and folks don’t realize that this isn’t like “Hey, I’m having a party, show up if you can” - it’s more “Hey, I truly need some help, so if you say you’re going to make it, I need to actually be able to count on you to be there 100% guaranteed.” Plus, it’s difficult work, lots of lifting and digging and such, and it’s not for everyone, so you sort of “burn through your contacts list” pretty quickly looking for folks. I was working on getting crew together until a week ago.
  • We probably could have gone just a tad faster. Looking back at the video, things felt a little slow overall. I don’t remember it being that way when we were there, and watching fireworks on video is sort of dumb and anticlimactic anyway, but there were a few dead spots where I feel like we should have had something in the sky. Granted, we couldn’t have gone too fast or the show would have finished in ten minutes or less… but I think this was maybe more of a 12 - 15 minute show than the 18 minutes we got out of it. Live and learn. You don’t really get to “practice” this stuff.

All in all, it was a great show.

As for next year, I’m not sure what the plan is. It was so hard to get a crew together this year, and there was so much work around coordinating the whole thing - getting the truck, scheduling people to be where they need to be, making sure people have their questions answered, following up to make sure everyone brought everything they were supposed to, etc.

  • that it’s really started to be much less fun than it used to be.

In some cases getting a show together is like getting a small wedding together. Is the caterer there? Did the cake arrive? How many people are showing up? Did you plan for enough food? Too much food? Where the hell is the groom? In the end, I’m questioning whether it might be time to take a break.

If I do, I’d either have to let my pyro license expire or do a make-up show (since you have to have a minimum number of shows to renew your license)… but the only reason I have my license is to do shows, so it’s sort of Catch-22-ish. The only reason to be licensed besides that is basically just to have the ability to say I’m licensed.

Anyway, something to think about. In the meantime, we had a great show this year, so thanks to the crew for all their hard work in making it happen!

media comments edit

I went looking for a list of YouTube URL hacks so I could send a link to a video and have it start at a particular time. I ended up coming across a couple of great posts that have some neat tricks.

My favorite two:

  • View high quality videos: Add “&fmt=18” for stereo 480 x 270 resolution or “&fmt=22” for stereo 1280x720 resolution.
  • Start at a specific time: Add “#t=XmYs” where X is the number of minutes and Y is the number of seconds, like “#t=5m16s” to start at 05:16. If you just want seconds (like to start at 0:14) you can just put the number, like “#t=14”.

Check out the rest of the tips on the original sites - good stuff!

net, aspnet, testing, gists, csharp comments edit

The VirtualPathProvider class is (in my opinion) a fairly underused mechanism for extending where different files in your application come from. You can create providers that get files from zip archives, databases, or anywhere else you need.

The problem is, unit testing them is a nightmare. You either have to run the tests from inside a real web app or you have to set up so many mocks that your tests become fragile or unmanageable. Ugh.

Turns out there’s a third option - create a special AppDomain that has just enough real setup to support working with the ASP.NET HostingEnvironment and VirtualPathProviders.

Here’s a sample test fixture that does just that:

using System;
using System.IO;
using System.Reflection;
using System.Web.Hosting;
using NUnit.Framework;

namespace MyTests
{
  [TestFixture]
  public class MyTestFixture
  {
    // Instance property for the HostingEnvironment-enabled AppDomain.
    private AppDomain _hostingEnvironmentDomain = null;

    [TestFixtureSetUp]
    public void TestFixtureSetUp()
    {
      // Create the AppDomain that will support the VPP.
      this._hostingEnvironmentDomain =
        AppDomain.CreateDomain("HostingEnvironmentDomain",
        AppDomain.CurrentDomain.Evidence,
        AppDomain.CurrentDomain.SetupInformation,
        AppDomain.CurrentDomain.PermissionSet);

      // Set some required data that the runtime needs.
      this._hostingEnvironmentDomain.SetData(".appDomain", "HostingEnvironmentDomain");
      this._hostingEnvironmentDomain.SetData(".appId", "HostingEnvironmentTests");
      this._hostingEnvironmentDomain.SetData(".appPath", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
      this._hostingEnvironmentDomain.SetData(".appVPath", "/");
      this._hostingEnvironmentDomain.SetData(".domainId", "HostingEnvironmentTests");

      // Initialize the hosting environment.
      HostingEnvironment environment = this._hostingEnvironmentDomain.CreateInstanceAndUnwrap(typeof(HostingEnvironment).Assembly.FullName, typeof(HostingEnvironment).FullName) as HostingEnvironment;

      // Finally, register your VPP instance so you can test.
      this.Execute(() =>
        {
          HostingEnvironment.RegisterVirtualPathProvider(new TestVirtualPathProvider());
        });
    }

    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
      // When the fixture is done, tear down the special AppDomain.
      AppDomain.Unload(this._hostingEnvironmentDomain);
    }

    [Test]
    public void FileExists()
    {
      // Use the special "Execute" method to run code
      // in the special AppDomain.
      this.Execute(() =>
        {
          Assert.IsTrue(HostingEnvironment.VirtualPathProvider.FileExists("~/Root/Folder1/Page1.aspx"));
        });
    }

    // This method allows you to execute code in the
    // special HostingEnvironment-enabled AppDomain.
    private void Execute(CrossAppDomainDelegate testMethod)
    {
      this._hostingEnvironmentDomain.DoCallBack(testMethod);
    }
  }
}

The difficult bit is setting up the special AppDomain, but once you do that and initialize the HostingEnvrionment, you can use the VirtualPathProvider just like you would in a real environment. The special AppDomain thinks the “root” of your application is in the same location as the executing unit test assembly, so there shouldn’t be any issues with the runtime locating assemblies or anything.

Standard disclaimers apply: YMMV, I’m not responsible if it crashes your server, etc.

media, windows, synology comments edit

That headline sounds a little foreboding, but this is important: If you are expanding your storage at home, be careful of choosing WD Green drives - only certain model numbers are good.

A while ago I upgraded my Windows Home Server storage with an eSATA port multiplier and some 1TB WD Green drives. A few months later I added more storage in the form of a 2TB WD Green drive.

During this time, I had installed PerfectDisk on the Windows Home Server and was using that to defrag my drives. When running it, I’d get all sorts of errors on random drives… but during regular day-to-day use, there were no problems. I was pretty well convinced this was a problem with PerfectDisk since that application was the only one causing issues. I couldn’t have PerfectDisk enabled for more than a couple of days before the server would blue screen or hang and require a hard reboot.

After all of this trouble, I started losing faith in the reliability of the server and got a Synology DS1010+ to move my DVD images to - the primary bulk of my data. While researching compatible drives for the DS1010+, I found that there are actually specific notes on their compatibility list about certain model numbers of the WD Green drives testing well and most others causing problems. There are forum posts about this as well.

Per these sources, the only reliable WD Green model numbers are:

  • 2TB: WD20EADS-00R6B0
  • 1.5TB: WD15EADS-00R6B0
  • 1TB: WD10EADS-00L5B1

I looked at my drives in my Windows Home Server and, sure enough, about half of the drives were the “good” model numbers and half were “bad” models. As part of the move to the DS1010+, I reorganized the drives in my Windows Home Server so only the “good” model numbers remained in the system.

I’ve been running PerfectDisk on the Windows Home Server for a little over two weeks now with no issue.

There are a lot of factors in play here, to be sure.

  • I moved the drives in the WHS around so they’re in different slots than they originally were. If there was some sort of problem with a drive being seated incorrectly or a particular slot disagreeing with a particular drive, that may no longer exist.
  • There are fewer drives in the eSATA port multiplier just because there are fewer drives in the system in general. If the port multiplier didn’t like having so many drives in it, that issue may not be showing itself now.
  • I moved several terabytes of data off the home server so the majority of the space there is empty. If the problem was with PerfectDisk managing drives that have very little free space, that may not be displaying now.

Even given all of that, it’s hard for me to deny that my experience with these drives is backed up by Synology testing and user experience, too. It’s not just me. Moving these drives out of my system seems to have increased reliability quite a bit.

YMMV, but my recommendation: Beware the WD Green drives.