Monday, July 31, 2006

PPD 8



Just a picture of a happy dog, with the minor compositional gimmick of having him pointing out of the edge of the frame.

Edits: Cropped
Taken: Monday, July 31st

I Should Really Be More Sore

Well that was one busy weekend.

Saturday was our long-planned paintball outing. For those of you who haven't played outdoor paintball, it's an extremely athletic sport. Lots of sprinting, crouching behind cover, crawling around and possibly cringing in terror. Oh, not to mention getting smacked with 68-caliber balls of paint moving a few hundred feet/second. Doesn't sound that bad, until you realize it's not far off from getting shot by a 58-caliber musket. Of course the musket has roughly 30 times the muzzle energy, but that's probably a good thing. And you can definitely get some nasty welts from a paintball gun.

But as I said, I managed to avoid most of the welts and also most of the soreness. Which was fortunate because the following day Wendy & I were signed up the Denver Urban Assault Race. The race is less competitive than most. The organizers set out a number of checkpoints around the city which you can visit in any order using almost any route. At each one there's a challenge, such as a scavenger hunt, bigwheel race, or sack race. They also do goofy things like make you bike around with helium burrito tied to your back. At the very end are the really fun challenges - the foam pit and the inflatable waterslide. Ah, good times. We ended up 30 of 42 in our division, and 49 of 70 overall. Not too bad considering neither of us bike much, and Wendy didn't even own a bike until a month again. I didn't even have to feel guilty about eating a giant burrito, because it came at the end of a 20+ mile bike ride.

Sunday, July 30, 2006

PPD 7



I just thought this was funny. What is that sign trying to tell you? "Handicapped people, engage antigravity here"? "This is where the aliens take people from (but only those in wheelchairs)"? Yeah, not real deep thoughts, but there it is.

Edits: Cropped
Taken: Monday, July 24th

Saturday, July 29, 2006

Paintball Smackdown

We just returned from the much-talked-about Newsgator/Encana paintball outing. I think it's safe to say a good time was had by all, and that we all sweated out roughly half our body weight.

Quite a few good welts resulted. Check out the pictures. I'm proud to say that I was a part of some of these, in the sense that I pulled the trigger. Props to everyone for being a good sport, especially Rob & Ronnie.

PPD 6



For some reason I've been looking at the tops of buildings lately, more as geometric abstractions than actual buildings. Plus, I didn't have a camera yesterday. So this is what I've got. :)

Edits: Cropped, histogram adjust x2
Taken: Thursday, July 29th

Thursday, July 27, 2006

PPD 5



This is the Holy Ghost Building on the east side of downtown. I sometimes think that my life revolves around this building in a literal, geometric sense. It's just about halfway between home and work, I walk towards it in the morning and circle around it on the way home.
The picture I like because it's just such a clean composition.

Edits: cropped, clone brushed out a tiny cloud
Taken: Wednesday July 26th, 2006

PPD 4



I don't even know why I like this one. Perhaps just the incongruity of the big stuffed monkey left in the middle of a park.

Edits: cropped
Taken: Monday, July 24th 2006

Tuesday, July 25, 2006

PPD 3



This is just a puddle in the alley across the street from work. I like the contrast between the clean regularity of the building reflected in the puddle and the dirty irregularity of the alley and the edge of the puddle.

Edits: Just cropped
Taken: Tuesday July 25th, 2006

Monday, July 24, 2006

Pictura - Friday, July 21st 2006


This is a picture of the office on Friday night after almost everyone was gone. It felt appropriate because this was end of a very long week, including one 18 hour day. I'm going for that "late night" kind of feel here.

Effects: Crop, histogram adjust, mild gaussian blur
That's more effects than I really wanted to do, but I think it's a better picture for it. Basically just enhanced the mood a bit.

Political Comedy

According to the Detroit News John Kerry recently made some interesting comments in reference to the Israel-Lebanon-Hezbollah conflict, to wit:

"If I was president, this wouldn't have happened," said Kerry during a noon stop at Honest John's bar and grill in Detroit's Cass Corridor.

Bush has been so concentrated on the war in Iraq that other Middle East tension arose as a result, he said.

"The president has been so absent on diplomacy when it comes to issues affecting the Middle East," Kerry said. "We're going to have a lot of ground to make up (in 2008) because of it."

...

"This is about American security and Bush has failed. He has made it so much worse because of his lack of reality in going into Iraq.…We have to destroy Hezbollah," he said.


I think this may be one of those rare moments when we can all disregard for a moment our political leanings, and personal feelings about John Kerry. A moment when we can join together in asking "What the hell is he smoking?" I mean really, every part of the article that involves Kerry reads like a joke. Let's review it in slow motion.


"If I was president, this wouldn't have happened", said Kerry during a noon stop at Honest John's bar and grill in Detroit's Cass Corridor.

So Mr. Kerry would've averted this crisis. It's pretty easy to say things like that when you'll never have to back it up. But it must be the truth because he was standing in Honest John's! I know it doesn't really pertain to his statement, but is that not the most ironic place a politician could possibly be quoted from? Like I said, the whole thing's a joke.


Bush has been so concentrated on the war in Iraq that other Middle East tension arose as a result, he said. "The president has been so absent on diplomacy when it comes to issues affecting the Middle East," Kerry said. "We're going to have a lot of ground to make up (in 2008) because of it."

So Bush was so concentrated on the Middle East that he lost site of... the Middle East? Um, right. And because of that, "tensions arose," implying that there were no tensions before, and they could've been avoided entirely with just a tiny bit more talking.

Let's remember that we're talking about the Middle East, possibly the most war-torn piece of real estate in human history, a region that practically every national leader in the last 30+ years has tried to bring peace to. But apparently, despite that long history of conflict, everyone was on the verge of a regional chorus of "Give Peace A Chance". But then Bush didn't come to the recital, so they went back to killing each other instead. Yep, that's exactly what happened, I know so because Mr Kerry said it while standing in Honest John's! Give me a break.


Hezbollah guerillas should have been targeted with other terrorist organizations, such as al-Qaida and the Taliban, which operate in Afghanistan and Pakistan, Kerry said. However, Bush, has focused military strength on Iraq.
"This is about American security and Bush has failed. He has made it so much worse because of his lack of reality in going into Iraq... We have to destroy Hezbollah," he said.

The first part stands on it's own, but this is really the punchline. After he says we're not being diplomatic enough, he follows up by essentially saying "Now I guess we'll just have to kill 'em all. That's what I would've done from the start, of course." Now that is what I think of when someone says diplomacy. I know politicians are a breed apart, but really how can he say this with a straight face? First there's not enough diplomacy, then the problem is that we didn't kill them fast enough? It sounds like what you'd get if you spliced Clinton and W into the same body - "We should've been more diplomatic and killed those bastards years ago."

Honestly, I don't even know why I subscribe to Dilbert anymore. I should just subscribe to this sort of thing instead.

Sunday, July 23, 2006

Pictura Per Diem

I've been an amateur photographer for a while, but I haven't really been keeping up with it lately. In an effort to get back into it a bit I've decided to try to start taking at least one picture every day. I'm not sure how well this will work out, since I spend most of my time between home and work. I might end up taking a lot of really crappy pictures and subject you poor people to them. But I'm hoping that it'll force me to be a little more observant, a little more creative, and perhaps a bit more flexible. With a little luck it might make a good reason to get out of my rut, at least far enough to get a decent shot :)

The rules I've created for myself:

  1. I won't post more than one picture from a given day. You wouldn't really want to see more than that anyway.

  2. Editing will be kept to a minimum - cropping, and maybe a bit of brightness correction. No airbrushing unless I'm really bored that day. Any digital editing I do will be noted.

  3. If I really just don't have anything even remotely viewable, I won't inflict it on you.

  4. The world already has too many pictures of flowers (some of them done by me). So no more of that.



I was going to call this little venture Picture A Day, but I think we can all agree that's a lame name. I figured Latin makes anything sound sophisticated (or at least snooty), hence the name Pictura Per Diem. And now, enough of the overly long introduction, and now on to the first Pictura.


I took this on my way to work Thursday morning. I just like the bright splash of the yellow car at the end of the alley. Pretty simple really. I wish I could've gotten rid of the rest of the clutter, maybe done something with depth of field, but my little compact pocketcam just isn't up to it.


Editing: Cropped (brutally), highlight/midtone/shadow adjusted

Tuesday, July 18, 2006

Goof Off Break

To take a break from all the heavy technical .NET stuff, look at these pictures!

Caricature
Last Saturday Wendy & I went to her company party at the zoo. They had a free caricature artist there, so we had a sketch done. Regrettably I don't have a scanner, so I had to take a picture of the drawing and then Paintshop it a bit.

Wendy's an elephant fanatic, so the tiny pachyderm makes sense. I'm not sure why I'm holding that weird stick. Or why I've got a Patrick Stewart haircut. Or why I look stoned. Come to think of it, I don't think that sketch artist liked me very much...




Toys


This other one is a picture of my little toy collection at work. Mostly I took this picture for Mom, because she bought most of this stuff for me. See Mom, I DO use it! Anyway, on the left there's a Darth Vader Pez dispenser. Next to him is the crazy posable magnetic robot thingy (technically it's an Acrobot), to which we've attached some Google marketing swag. He's trying to get his foot free of the magnetic Tree with Bluebirds (love that creative name). Next to that is the Monty Python Dark Knight Bobblehead, which is actually from Wendy.

Good stuff. :)

Upgrading Newsgator Online, part 2

This is a continuation of our adventures in upgrading the Newsgator online application to ASP.NET 2.0. Part one, which focuses on just the C#/Microsoft related issues that we found during the process, is here. In this part I will cover the prerelease process leading up to our first deployment attempt.

Before we begin...

These posts focus on what I did in the deployment, so they tend to sound a bit like I'm the only one that did anything at all. That's just because those are the things I know about. Everyone else on the online team worked their tails off as well, with a lot of support from others in the company. They all did tons of testing, fixing, verifying and other things I never heard about. Any software project this large is a team effort, including this one.

Always be prepared

This was a large, scary upgrade from the beginning. Our web servers host all the Newsgator online applications, which includes Newsgator.com, all the Whitelabel sites, Whitelabel Admin, Buzz (or whatever we're calling it today), Denver Post Newshound, all the VNU Newsgator sites, an internal admin application and one app that's in quasi-production. For better or worse, we decided that everything but VNU should be upgraded in one fell swoop. Thankfully the Newsgator API has been moved to it's own cluster, so there was almost no way we could break the USA Today reader. Still, we were upgrading 7 different applications at once.

We had a very aggressive schedule for the migration, roughly four weeks. But that includes all the time to branch source control, upgrade all the developer machines and servers, migrate the code and write the deployment plan. Oh yeah, and test stuff too.

We typically do about a week of testing for an incremental upgrade, but in this case we were changing the entire underpinnings of the application, the very foundation the websites stand on, in addition to a nearly full schedule of new features. A full regression test is really what we needed, but we just didn't have the 2+ weeks that would have taken. Our testers, Ria and DeDe, did a really great job with the time they had. Unfortunately, halfway through testing Murphy's Law kicked in. DeDe, our tester for Newsgator.com, got an unscheduled root canal and was out for almost three days. The rest of the team worked hard to pick up the slack, and we found a few bugs, but nothing too terrible. At this point I was cautiously optimistic about the deployment. I should've known better. Developers generally make terrible testers, and this was no exception.

Deployment Day #1

Our first shot at deployment was on a Thursday. DeDe was well enough to come back to work, and she began testing with a vengeance. That day was absolutely crazy. DeDe found a bunch of bugs, including something like 8 showstoppers. These ranged from minor display problems to major crashes, ASP.NET 2.0 bugs to configuration problems. It turned out that many of the issues stemmed from a source control crash we had back in May. We thought that had been cleaned up, but many of the files in source control were the wrong versions. So on top of upgrading we had to recheck everything we got from source control. The whole team fixed bugs frantically, but we were barely keeping up with the bug reports. The last fix was completed barely an hour before the deployment was scheduled to begin, with no time to verify it. Nonetheless we zipped up the code and started copying to production.

At this point any experienced developer should have warning bells, along with sirens, flashing lights, and the red alert klaxon. When you're still finding critical bugs the day of deployment, you're not ready to deploy. Despite that we almost deployed anyway. We even had a meeting with the entire development staff to talk it over. Frankly, it was kind of comical. We all immediately agreed that deploying was a stupid idea. Then we discussed whether to do it anyway. Thankfully, reason prevailed and we scrubbed it. The new deployment date was set for just two working days later, on Monday night.

Barely an hour later that decision was vindicated. We discovered that if we had loaded, we would have broken the Newsgator support forums. By itself that wouldn't have been a critical issue, but as it turned out that was just the tip of the iceberg.

Off-The-Shelf doesn't mean easy

Originally we had thought the forums could just be left alone, running on the 1.1 framework. Due to some oddities in our setup, it turned out to be impossible to upgrade Newsgator.com without also upgrading the forums. We tried running them under 2.0, but ran into some problems I described my previous post. Instead of fighting it, we decided to just upgrade to the latest version. Remember when I said we were upgrading seven applications? Make that eight.

We obtained the latest version of the software from the vendor. They had upgrade instructions, database scripts, new binaries, even the source code. What could be easier? I ran the upgrade scripts on the staging database, copied the new binaries and pages in, and was ready torock."I love off-the-shelf software!" I thought.

There were a few problems. In previous versions of the forums there were RSS feeds available for each of the forums. We made heavy use of these, since we are an RSS company. But for some inexplicable reason the vendor changed the way this was done and broke backwards compatibility. Unfortunately I don't have the option to break those feeds, because it would just be ridiculous for an RSS company to break their own feeds.

The vendor was of little help in the admittedly short timeframe available, so I ended up applying a little hackaround. I coded up a quickie HttpModule to look for the old urls, and return an HTTP 301 (Permanent Redirect) to the new ones. Any decent feed reader will update it's links based off of that. In particular, all of Newsgator's readers handle 301's properly - and who would use any other reader? :)

Another problem, the upgrade had dropped the branding on the forum site. Not only that, but they had completely changed the way customization was done. Thankfully some creative copy and pasting got things looking more or less the same as they had.

Those solved, the forums seemed to be humming right along. Once again, I was feeling optimistic about the load. We had fixed most of the problems in our software, and the forums were off-the-shelf, so there couldn't be anything wrong there. Apparently I just don't learn...

Next time, deployment #2...

Friday, July 14, 2006

ASP.NET 2.0 migration

We're in the middle of migrating all of our websites to the latest version of the Microsoft KoolAid, in this case .NET 2.0 (and ASP.NET 2.0, C# 2.0, and probably SomethingElse 2.0 too).

We did a fair amount of prep work this, reading the various migration guides, talking to another group at Newsgator that has already migrated, I even read the entire list of breaking changes. Of course we still had difficulties, so here is my list of lessons learned.

Field name separator changes

The names for form fields in ASP.NET are constructed by concatenated all the parent control IDs with a delimiter in between. In ASP.NET 1.1 that delimiter was always a colon character. So a field might have a name like "ctl1:ctl2:ctl3:txtTextBox" (if you're not into giving your controls good IDs).

Under 2.0 the delimiter has changed - sometimes. It turns out the which delimiter you get is determined by the xhtmlConformance attribute in your web.config. I which values give you which delimiter is left as an exercise for the reader.

Of course, you're never supposed to construct these name strings yourself - that defeats the whole purpose of ASP.NET. I imagine that's why this wasn't listed as a breaking change (it wasn't, I checked). But people still do it. People like us, evidently.

Event Validation

ASP.NET 2.0 added a new feature called Event Validation. I found a decent explanation for it at OdeToCode. It's a neat sounding feature, and the implementation sounds quite clever, but I'm still baffled and annoyed by this feature. Isn't the first rule of web development "Thou shalt not trust the client"? Haven't we all learned to validate all input from the client? If you're checking input like you should be, this feature is totally redundant. On top of that, it increases page bloat by adding the validation data to the page source and throws unfriendly exceptions to the users.

Turning this off was a no-brainer.

Web Project Formats

With the upgrade to Visual Studio 2005 Microsoft inexplicably decided to change the way web projects are handled. They've already been badly beaten up about this, and frankly they deserved it. It was a really dumb idea. But they've partially atoned for the sin by releasing a patch to support the old formats, which they're now calling the Web Application Project format, as opposed to the Web Site format.

This is all great, but apparently Visual Studio never got the memo. Some of our developer's machines insist on switching our projects to Web Site format every now and then. Just in the last week I've had to rollback that particular change two or three times. Even though it's a fixable and well documented issue, it still really really sucks.

FormsAuthentication changed more than you think

A couple important changes were made to FormsAuthentication. One is a bugfix, the other just a bug.

The bugfix is that in 1.1 if you set a persistent cookie it's lifetime was always 50 years, regardless of what the timeout attribute in the web.config said. In 2.0 the timeout value is respected. Unfortunately it was very easy to rely on that broken behavior before, as we were.

The outright bug is in the FormsAuthentication.GetLoginRedirect() function. This function is supposed to return the original URL the user was trying to get to before he was redirected to the login. But it turns out that if that URL had any query string parameters in it you get an exception like this instead:

System.Web.HttpException: The return URL specified for request redirection is invalid.
at System.Web.Security.FormsAuthentication.GetReturnUrl(Boolean useDefaultIfAbsent)
at System.Web.Security.FormsAuthentication.GetRedirectUrl(String userName, Boolean createPersistentCookie)


The only post we could find on the internet was from this post on HackedBrain. He is of the opinion that only certain characters cause the problem. We didn't test enough to figure it out, instead we just hacked together some replacement code:


string redirectUrl = Request["ReturnUrl"];
if(redirectUrl == null){
redirectUrl = Request.ApplicationPath + "/default.aspx";
}


Clientside Event Handlers

Perhaps the goofiest undocumented change is the handling of Javascript event handlers. We discovered this error in our third-party forums package. It was adding a clientside event handler using code like this:

myForm.attributes["onsubmit"] = myButton.ClientID + ".disabled = true;";

The control would then be rendered out with that attribute set as specified. For instance:
<form onsubmit="_ctl0_myButton.disabled = true;">
It took me a while to figure out how this ever worked. The onsubmit handler is executed in the context of the form, essentially the magical this pointer is set to the form. And the form automatically gets all the form fields set as properties. So the button is defined in that context. This is clever, but as it turns out it's too clever by half.

Turns out the vendor isn't the only one that's too clever by half. The 2.0 framework no longer blindly sticks things into attributes when you tell it to. It actually puts your script into a function and then calls the function. So the previous example might be rendered out like this:
<form onsubmit="WebForm_Submit()">
<script type="text/javascript">
<!-- function WebForm_Submit(){
_ctl0_myButton.disabled = true;
} -->
</script>
That extra level of indirection is enough to break things. The button variable _ctl0_myButton is no longer defined, and a script error is thrown.

How would one fix this? I've got some ideas, but this was in a piece of off the shelf software, and the beauty of COTS software is that it's NMFP (Not My Freakin' Problem).

To be continued...

Monday, July 03, 2006

God vs. WalMart

I've been reading Scott Adams' personal blog for a while now. He's sometimes thought provoking but mostly just funny. Anyway, that's just a lame intro for this quote from a post:

And what’s up with the people who pray for material things? If you believe that God answers prayers for merchandise, it means the gap between the Almighty creator of the universe and Walmart is closing. God still has the lowest prices and widest selection, but how long can that last?
It takes a true genius to compare the Almighty to Walmart, and make Walmart out to be the winner.