• Principles vs. Methods

    Ralph Waldo Emerson once said:

    As to methods there may be a million and then some, but principles are few. The man who grasps principles can successfully select his own methods. The man who tries methods, ignoring principles, is sure to have trouble.

    - Ralph Waldo Emerson (1803-1882)

    I like this quote in the context of software engineering. Bryan wrote a while back about Patterners vs Customizers, and Emerson's quote is along the same lines. 

    As developers we have a lot of methods to write software. We can use ASP.Net, SQL Server, LINQ, MSMQ, ORM... there's a long list of things we can use to accomplish our tasks. We even have other tools to support the process: TFS, Mercurial, BaseCamp, code reviews...

    What is more important is to understand the *why* behind these methods. *Why* do we do code reviews, or write unit tests, or use a source control system. It's not just to be able to check off a box. These activities are just manifestations of underlying principles that we believe to be true and good and virtuous.

    If we seek to understand the principles behind these methods, we stop performing rote tasks just because we "have" to, and we can begin to apply situational judgment and understanding. If we understand things like test driven development, or SRP, or SOLID, or avoiding premature generalization, it becomes much simpler to select the correct methods that match a given situation.

    Our principles should focus on providing business value at high quality. They should drive us to excellence in our designs and implementations. They should make us strive to do things right.

    If we focus only on the methods, we stay focused on just checking off boxes. As software engineers, we can provide much more value than that.

     

  • Doing work in a property? Back away from the keyboard....

    and spend some time reading the Framework Design Guidelines (FDG).

    Yesterday, I was perusing a profiling report* trying to pinpoint an obscure performance issue. What I found startled me. A single property getter was consuming a fifth of all CPU cycles. Twenty percent!

    The code itself *looked* innocuous. In fact, it was a single line of code performing a straightforward regular expression. The only problem was that this particular property was getting accessed all the time (there were some other design flaws that exacerbated the problem). The real shame is that this particular Boolean property could have been set once in the constructor. Sigh.

    Perhaps the Framework Design Guidelines need better iconography. Next to the statement "properties should not be computationally complex" I'd put the icon that signifies "fool me once, no more checkin rights for whomever reviewed your code. Fool me twice, no more checkin rights for you." Suggestions for what that icon looks like are warmly welcomed.

    *Props to the Visual Studio 2010 for making performance profiling super easy in 64 bit VMs. This was a huge pain in VS2008. In VS2010, it's as simple as "Analyze -> Profiler -> Attach".

  • Too many requests from the CDN? Try URL canonicalization

    Turns out URL canonicalization has benefits beyond SEO. Last week, I spent some time analyzing our IIS logs to help track down a performance issue. What I found surprised me. Our CDN (Akamai) didn't appear to be working properly.

    How many requests should you expect from Akamai?

    Akamai's architecture is pretty straightforward*. You make a request for msnbc.com content that's cached by Akamai (say http://www.msnbc.msn.com/id/42324795/ns/world_news-asiapacific/). Your request goes to one of Akamai's edge servers. If the content is already cached at the edge server and hasn't expired, it returns the content to you. If not, the request goes to one of Akamai's midgress servers. If the content is cached at the midgress server and hasn't expired, it returns the content you want to the edge server, which then hands it off to you. Otherwise, the request goes all the way to the msnbc.com data center (and is subsequently returned to the midgress server which returns it to the edge server).

    Based on this architecture, there is a theoretical upper bound to the number of requests that I should see at my origin servers for a given piece of content. Akamai won't reveal how many midgress servers they have, but it's safe to assume it's somewhere between 50 and 100. For the time being, let's a assume it's 75. Also, assume your cache TTL is measured in minutes. For a 24 hour period, the maximum number of requests our servers see should be:

    Max requests at origin = 1440 minutes per day / TTL * 70 midgress servers

    If your TTL is 1 minute, you could see up to 100K requests per day for a given piece of content.

    What were we seeing?

    For some content, I was seeing 5x the number of requests we should have been seeing. Before I lost my sanity asking our operations team for the 10th time to verify the Akamai configuration, one of my colleagues made an interesting observation (in this case, making an interesting observation is a euphemism for pointing out my folly).

    My analysis was based on content ID. If you looked at requests per URL (which is how Akamai caches things), there were 4 major variations and dozens of minor variations of the URL. The two variations at the top of the list? The trailing slash:

    /id/42324795/ns/world_news-asiapacific/

    /id/42324795/ns/world_news-asiapacific

     

    Problems like these have a two part fix:

    1. Issue a 301 redirect for any URL that isn't the canonical URL

    2. Consolidate your URL generation code - this is challenging if you're working on a sprawling legacy codebase

     

    *I've simplified the explanation a bit. First, Akamai employs a pre-fetching mechanism which can make your TTL seem much shorter. Also, I suspect Akamai actually serves stale content from the midgress and edge servers instead of blocking the end user request waiting for the stale content to get bumped out of cache.