Thursday, November 5, 2009

Azure CDN vs. Amazon CloudFront/S3

Earlier this summer we took a deep look at the CDN market, taking into account both established players (Limelight, Akamai, Level-3) and the emerging pay-as-you-go contenders (Amazon’s Cloud Front, Rackspace’s Cloud Files, SimpeCDN and the like). Today, ~1 week after Amazon’s Relational Database Service was announced, Microsoft responded with its own introduction of a new CDN that will offer 18 edge locations throughout the world [1] :

“Windows Azure CDN has 18 locations globally (United States, Europe, Asia, Australia and South America) and continues to expand. Windows Azure CDN caches your Windows Azure blobs at strategically placed locations to provide maximum bandwidth for delivering your content to users. You can enable CDN delivery for any storage account via the Windows Azure Developer Portal. The CDN provides edge delivery only to blobs that are in public blob containers, which are available for anonymous access.”

Note that the latest addition to the Azure family is in CTP release only. All we know is that, for the Windows Azure platform itself, PDC ‘09 (to be held later this month) is expected to announce new features and will be followed by an official launch in January and first billing cycle in February; it’s very likely that the CDN will be available along similar timelines as well.

Like CloudFront, Microsoft’s CDN doesn’t solve the HTTPS issue in its first release. In terms of pricing, if Windows Azure Platform Pricing is any indication, you can expect to pay ~0.17/Gb for each targeted zone.

As a refresher, Amazon uses 14 edge locations in major markets throughout worldwide: 8 in the United States (Ashburn, VA; Dallas/Fort Worth, TX; Los Angeles, CA; Miami, FL; Newark, NJ; Palo Alto, CA; Seattle, WA; St. Louis, MO), 4 in Europe (Amsterdam; Dublin; Frankfurt; London) and 2 in Asia (Hong Kong, Tokyo).

The North American edge locations are mapped below:


On the issue of TTLs, it’s still unclear whether the Azure CDN will support shorter TTLs required for niche applications:

“The TTL specifies that the blob should be cached for that amount of time in the CDN until it is refreshed by the Blob service. The CDN attempts to refresh the blob from Windows Azure Blob service only once the TTL has elapsed. The default TTL is 72 hours. At PDC 2009, we will allow you to specify the standard HTTP Cache-Control header for your Windows Azure blobs. If this value is specified for a blob, then the TTL period will be set to the value specified in Cache-Control header.”

And lastly, tools you need to get started with either service are the Azure Storage Explorer, the Amazon S3 Firefox Organizer (0.4.8) or CloudBerry Explorer (for S3 and Azure Blob Storage) – just note that, as Microsoft plays catch up here, the Azure tools don’t yet expose the same richness of features around CDN integration.


[1] – Introducing the Windows Azure Content Delivery Network

[2] – Using the New Windows Azure CDN with a Custom Domain

Tuesday, November 3, 2009

LinkedIn vs. StackOverflow & The Shifting Landscape for Programming Careers

I’ve been curiously watching LinkedIn try to transform itself into an awkward Q&A-style forum. Subscribing to the Senior .NET Developers group recently, I was a bit surprised to see the type of tactical and specific implementation questions being posted.

This is a terrible pairing of technology, IMO. Sure, LinkedIn is great at building and exposing the professional web, but their Q&A offering is almost an after-thought with a feature set that’s at least 5 years dated.

Even worse, none of this dialogue is publically searchable!

We’ve written about the value of StackOverflow reputation rankings as an emerging compliment to traditional resumes and awards. Yes, the current scoring system leaves much to be desired: users are more incentivized to create ‘popular’ content that drives participation than accurate, factual content that doesn’t.

The score itself is less telling than a closer examination of an individual’s responses. Nonetheless, it is best-of-breed and it’s no surprise that they announced a new career site today specifically intended to link hands-on Q&A activity with public CVs.

Stack Overflow Careers

What is It's a few things: 

  • a completely free, public CV hosting service for programmers, to share the cool stuff you've coded and created with the world.
  • a way to explicitly link your Stack Overflow profile with your CV, to provide concrete examples of your communication skills and individual expertise to anyone who is interested.
  • a better way to connect great programmers with the best programming jobs, for those who opt into the small annual listing fee.

Prior to the announcement, bloggers were already starting to sport “My answers @StackOverflow” feeds alongside their content, courtesy of the user-specific RSS feed exposed by StackOverflow and tools like Yahoo Pipes – the new careers site formalizes this intention in a much cleaner way.

Joel had a great post this week on finding out what your company is all about and the theme of helping your users become awesome that really resonated with me – they’re certainly living this out loud with this launch:

If you love to code, too, I encourage you to create your own Stack Overflow CV. Keep it private, or make it public via the URL of your choice -- it's completely free either way. If you think you might be actively looking for a job in the next 3 years, take advantage of our outrageously low promotional pricing of $29 for a 3 year filing. That way, at any point in those 3 years, you can flip a switch and become visible to hiring managers. Or not. It's totally up to you.

It’s refreshing to watch these guys in action and I can’t wait to see how it evolves!

Sunday, November 1, 2009

CompilationMode=Never: What does it actually do?

I wanted to take CompilationMode=Never for a test-drive on an existing application that’s plagued by too many control/page assemblies – the goal was to see if this would help improve scalability (by reducing unrecoverable memory consumed by assemblies) and to observe its impact on a high and fluctuating ‘% time in JIT’. It turns out that it’s not as easy as throwing it into web.config.

Yes, you can apply this en masse to an existing website but doing so on pre-existing sites could generate:

  1. The attribute 'codefile' is not allowed in this page.
  2. The attribute 'autoeventwireup' is not allowed in this page.  

Why would CompilationMode interfere with AutoEventWireup? In automatically wiring up events, it looks like the framework looks for suitable signatures at runtime using reflection [1] – crazy, I know; and not having assemblies would presumably make this impossible to do. Scott Allen has a couple of good writes-ups on this and you can have a look for yourself in the auto-generated assemblies.

Can you think of any reasons why the events wouldn’t be wired up at compile time?

I tried to debug the framework to see this in action but threw in the towel after a few hours of fighting the symbol server – hours on this is pretty ridiculous, I know, and in complete defiance of Oscar’s #1 rule: stops are in, emotions are out! It was just a bit shocking to see how brittle the entire setup around source server is and how many continue to struggle with it [2] – anyone out there actually using it successfully for mscorlib and System.*.dlls? Have you you applied any service packs? Would love to hear from you. With VS2008 SP1 (9.0.307279.1), Vista SP2, the latest source code component (Dotnetfx_4016_VistaSP2), and following every instruction to a tee, I can step into most assemblies (e.g. System.Web, 2.0.50727.4016) but can’t step into mscorlib (2.0.50727.4200) which contains the reflection calls in question – for reference, the symbols for mscorlib are downloaded from /download/symbols/mscorlib.pdb/4D0B2695F5144B4D8F24004284FE26191/mscorlib.pd_.

So once you’ve manually resolved #2, code-behind files must also be pushed out to a fully-qualified class that can be reference by the Inherits attribute alone. 

After that, it works as expected and you see the runtime behaviour of CompilationMode=Never:

   1: // IWebObjectFactory.CreateInstance 
   2: public virtual object CreateInstance() {
   4:     // Create the object that the aspx/ascx 'inherits' from
   5:     TemplateControl templateControl = (TemplateControl) HttpRuntime.FastCreatePublicInstance(_baseType);
   7:     // Set the virtual path and TemplateSourceDirectory in the control 
   8:     templateControl.TemplateControlVirtualPath = VirtualPath;
   9:     templateControl.TemplateControlVirtualDirectory = VirtualPath.Parent; 
  11:     // Give the TemplateControl a pointer to us, so it can call us back during FrameworkInitialize
  12:     templateControl.SetNoCompileBuildResult(this); 
  14:     return templateControl;
  15: }

What’s a little surprising, if I’m reading this right, is it seems to generate the type on demand every time without any caching of the instance for re-use across different requests:

   1: /*
   2:  * Faster implementation of CreatePublicInstance.  It generates bits of IL
   3:  * on the fly to achieve the improve performance.  this should only be used 
   4:  * in cases where the number of different types to be created is well bounded.
   5:  * Otherwise, we would create too much IL, which can bloat the process. 
   6:  */ 
   7: internal static Object FastCreatePublicInstance(Type type) {
   9:     // Only use the factory logic if the assembly is in the GAC, to avoid getting
  10:     // assembly conflicts (VSWhidbey 405086) 
  11:     if (!type.Assembly.GlobalAssemblyCache) { 
  12:         return CreatePublicInstance(type);
  13:     } 
  15:     // Create the factory generator on demand
  16:     if (!s_initializedFactory) {
  18:         // Devdiv 90810 - Synchronize to avoid race condition
  19:         lock (s_factoryLock) { 
  20:             if (!s_initializedFactory) { 
  21:                 s_factoryGenerator = new FactoryGenerator();
  23:                 // Create the factory cache
  24:                 s_factoryCache = Hashtable.Synchronized(new Hashtable());
  26:                 s_initializedFactory = true; 
  27:             }
  28:         } 
  29:     } 
  31:     // First, check if it's cached 
  32:     IWebObjectFactory factory = (IWebObjectFactory)s_factoryCache[type];
  34:     if (factory == null) {
  36:         Debug.Trace("FastCreatePublicInstance", "Creating generator for type " + type.FullName);
  38:         // Create the object factory 
  39:         factory = s_factoryGenerator.CreateFactory(type);
  41:         // Cache the factory
  42:         s_factoryCache[type] = factory;
  43:     }
  45:     return factory.CreateInstance();
  46: } 

Anyway, if SharePoint uses it successfully, I’m sure it can work for your CMS/cutting-edge-ASP.NET-stuff too.

Performance benchmarks though will have to wait another day.


[1] – AutoEventWireup & Reflection

[2] – Troubleshooting Framework Debugging

[3] – Microsoft Reference Source Server

[4] – KB944899 (This hotfix addresses a performance problem when stepping through Source Code downloaded via a Microsoft Reference Source Server)